12

Maybe it is a stupid question, but i'm new to ruby, and I googled it, found these:

proc=Proc.new {|x| deal_with(x)}
a_lambda = lambda {|a| puts a}

But I want this:

def forward_slash_to_back(string)
...
def back_slash_to_forward(string)
...
def add_back_slash_for_post(string)
...
...
case conversion_type
when /bf/i then proc=&back_slash_to_forward
when /fb/i then proc=&forward_slash_to_back
when /ad/i then proc=&add_back_slash_for_post
else proc=&add_back_slash_for_post
end

n_data=proc.call(c_data)

But it gives me an error. I don't know how to do that in Ruby, anyone can help? thanks a lot!

aaron
  • 1,951
  • 3
  • 27
  • 41
  • Out of curiosity, what problem are you trying to solve? How did you end up needing to jump through all these hoops? Or just academic? – JD. Apr 27 '15 at 16:59

1 Answers1

26

"Function pointers" are rarely used in Ruby. In this case, you would normally use a Symbol and #send instead:

method = case conversion_type
  when /bf/i then :back_slash_to_forward
  when /fb/i then :forward_slash_to_back
  when /ad/i then :add_back_slash_for_post
  else :add_back_slash_for_post
end

n_data = send(method, c_data)

If you really need a callable object (e.g. if you want to use an inline lambda/proc for a case in particular), you can use #method though:

m = case conversion_type
  when /bf/i then method(:back_slash_to_forward)
  when /fb/i then method(:forward_slash_to_back)
  when /ad/i then ->(data){ do_something_with(data) }
  else Proc.new{ "Unknown conversion #{conversion_type}" }
end

n_data = m.call(c_data)
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
  • 2
    One could mention that there is no such thing as a "function pointer" in ruby. And it'd basically be useless (as in most dynamic languages). – Romain Nov 11 '11 at 15:11
  • 6
    @Romain: as informal as "function pointer" sounds, we can understand it as "how do I store a function (block/method) in a variable without actually calling it". In Ruby this is no exactly trivial since blocks are first-class objects but methods are not (you need `obj.method(name)` to get it as a block) – tokland Nov 11 '11 at 15:22
  • Marc-André: I don't see the need for the second example, since you'd write `method(m)` at then end and keep using just symbols in the `case`. Note also that the first `case` shadows the "method" method with a variable "method" and it may confuse the OP (I got confused just writing it :-p) – tokland Nov 11 '11 at 15:26
  • 1
    @tokland: agreed. I've edited the second example to make it meaningful. – Marc-André Lafortune Nov 11 '11 at 15:33
  • @Marc-André: indeed, if the case returns blocks from heterogeneous sources it does make sense. – tokland Nov 11 '11 at 15:35
  • @tokland I get your point, though the way the question is asked seems a lot like the OP's author comes from a language that does function pointers, and if that is so, it can be nice going the extra mile and explaining why the exact same concept makes little sense in the context of ruby. – Romain Nov 11 '11 at 15:42
  • thanks all of you for the quick responses and that is really helpful! – aaron Nov 11 '11 at 15:56
  • It would be nicer if the usage was more natural, e.g. method(c_data) or m(c_data) instead of send(method, c_data) or m.call(c_data). – mvw Jan 28 '14 at 15:27