Kokizzu
Kokizzu

Reputation: 26908

How to pass multiple function as argument in Ruby?

I have three functions A, B, and C. I need to pass A and B to C. How can I do this?

def A a
end

def B b
end

def C( &f1, &f2 ) #  syntax error, unexpected ',', expecting ')'
  f1.call 123
  f2.call 234
end

def C( f1, f2 ) # this one ok
  f1.call 123
  f2.call 234
end

C( &A, &B) # syntax error, unexpected ',', expecting ')'

Upvotes: 0

Views: 657

Answers (2)

engineersmnky
engineersmnky

Reputation: 29598

I would recommend using Object#public_send to perform this operation although I think there are probably better ways to handle your situation if you were to define it more clearly.

Also in only constants should be capitalized methods should be defined in lower snake case.

Example:

#puts used for clarification purposes
class SomeClass
  def a(val)
    puts "method a called with #{val}"
  end
  def b(val)
    puts "method b called with #{val}"
  end
  def c (f1,f2)
   public_send(f1,123)
   public_send(f2,234)
  end
end

Usage

s = SomeClass.new
s.c(:a,:b)
#method a called with 123
#method b called with 234
#=> nil

Hope this helps you like I said if you define the use case more clearly there may be and most likely are better ways to handle the problem.

Note: the above code will not work in the context of main:Object directly when typed into irb. Instead it will inform you that a private method was called for main:Object. This is because when defining a method in irb it is privatized in the context of main.

Also note you could use Object#send but this will give access to private as well as public methods (which might be a security concern dependent upon usage)

Another option would be to define a and b as lambdas or Procs e.g.

a= ->(val) {puts "method a called with #{val}"}
b= ->(val) {puts "method b called with #{val}"}
def c(f1,f2)
  f1.call(123)
  f2.call(234)
end
c(a,b)
#method a called with 123
#method b called with 234
#=> nil   

Upvotes: 2

Kokizzu
Kokizzu

Reputation: 26908

there's a method method to convert function to method, so we can do this:

def A a
end

def B b
end

def C( f1, f2 ) # this one ok
  f1.call 123
  f2.call 234
end

C( method(:A), method(:B))

Upvotes: 0

Related Questions