1

How can I pass the results of a method to another method in ruby? eg:

class D
  def initialize(text)
    @text = text
  end

  def a s
    "hello #{s}"    
  end

  def b s
    "hi #{s}"
  end
end

So, what I want to do is pass the output of method a to method b. So essentially(if the methods aren't inside a class) I can do the following the following:

puts b(a "Tom") #=>hi hello Tom

However, even if this isn't inside a class, it wouldn't look good if there are a lot of methods so there must be a more elegant way to do this. So what is the proper way to get the output hi hello Tom by applying the methods a and b to an instance of the class D?

UPDATE I just wanted to make it a little bit more clear. Eg, in F# you can do something like this:

let a s = "hello " + s
let b s = "hi " + s
"Tom" |> a |> b #=> hello hi Tom

Here we defined functions a and b and then passed on the results to the next function. I know that its a functional language so ways of doing things would be different there. But I am just wondering if there are any such tricks in Ruby?

2
  • 1
    “so there must be a more elegant way to do this”—why is that? One might use puts b a 'Tom', but I doubt it’s “more elegant.” Commented Nov 23, 2016 at 13:10
  • 1
    The question remains: why on the Earth you think that F#’s way is more elegant? Commented Nov 23, 2016 at 13:30

1 Answer 1

6

You can leave the ()

def a s
  "hello #{s}"
end

def b s
  "hi #{s}"
end

puts b a "Tom"

If you have many methods :

puts [:a,:b].inject("Tom"){|result,method| self.send(method,result)}

If you want to use those methods with any object (including Classes) :

module Kernel
  def chain_methods(start_value, *methods)
    methods.inject(start_value){|result,method| self.send(method,result)}
  end
end

class D
  def a s
    "hello #{s}"
  end

  def b s
    "hi #{s}"
  end
end

class E
  class << self
    def a s
      "hello #{s}"
    end

    def b s
      "hi #{s}"
    end
  end
end


# Example with instance methods
puts D.new.chain_methods("Tom", :a, :b)

# Example with class methods
puts E.chain_methods("Tom", :a, :b)

# Thanks mudasobwa :
E.chain_methods("Tom", :a, :b, :puts)
Sign up to request clarification or add additional context in comments.

5 Comments

Yay, upvoted for puts [:a,:b].inject("Tom"){|result,method| Object.send(method,result)} :) puts could be chained too, btw.
Wow, this is great! thanks Eric. Now, how can I get the same result if the methods are inside a class, in my example lets say class D, so how can I get the result by applying methods to an instance of class D? Or should I instead use class methods for that?
@BA you can define instance by d = D.new("test") and call d.send instead of Object.send
Why do you send the methods to Object? In the original code, they are sent to self, so you are calling completely different method. Although, please use public_send instead, there's no reason to break encapsulation here.
I wanted the code to also work when a and b are defined in main, since the OP mentioned it. In that case, they are private methods, available to every object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.