1

I have a method that accepts a method as an argument:

def acceptor_method(received_method)
  an_arry.each do |attr|
    received_method if some_condition
  end
end

This works well if all the received_method does is run through some code:

def some_method
  do_something
end

Which is the equivalent of:

def acceptor_method(received_method)
  an_arry.each do |attr|
    do_something if some_condition
  end
end

But what if I want the received_method to break the loop and return a value, as with:

def acceptor_method(received_method)
  an_arry.each do |attr|
    return true if some_condition
  end
end

Unfortunately, this doesn't work:

def some_method
  return true
end

As it only returns true for some method, not for acceptor_method--which continues to play through the loop.

So is there a way to send a method that when run is the equivalent of return true?

nullnullnull
  • 8,039
  • 12
  • 55
  • 107
  • I'm not sure if I'm interpreting your scenario properly, but just in case, watch out for terminology. You aren't ever passing the actual method (like you would a function in JavaScript). If you were to do `acceptor_method(some_method)`, the `some_method` method would be immediately called and resolved, and its return value would be sent as a parameter to `acceptor_method`. You could, however, pass a symbol to `acceptor_method` and call `send(:your_method_name_symbol)` to dynamically invoke the method. Have I misunderstood your scenario? – Paul Richter Feb 03 '14 at 23:04
  • Thanks, Teeg. That clarifies a lot about how something like this would work. Unfortunately, I'm still struggling with the underlying problem, which is that I can't get `send(:method_symbol) if some_condition` to be the equivalent of `return true if some_condition`. The `return` within the received method remains caught within its own scope, so it does not return out of the acceptor method. – nullnullnull Feb 03 '14 at 23:26
  • Two questions: Hypothetically, where would `some_condition` come from? Also, when you say you want it to be the equivalent of `return true...`, do you mean that you basically want to call your "received_method" conditionally (depending on `some_condition`), and have it return a boolean, essentially? – Paul Richter Feb 03 '14 at 23:34
  • `some_condition` is defined within the `each` loop. (FYI, it's `changed_attributes.include? attr.key`) My goal is for the `received_method` to break out of the `each` loop and return `true` on behalf of `acceptor_method`--which I believe is what you're saying. – nullnullnull Feb 03 '14 at 23:43

2 Answers2

2

You can do this using blocks rather than methods. See How can I return something early from a block?

Basically if you have a block with break value and yield to it, the function will return value. Unfortunately I don't see a way to do this using methods, since Ruby really doesn't like having break outside of a block or loop.

Community
  • 1
  • 1
Max
  • 21,123
  • 5
  • 49
  • 71
2
def acceptor_method
  [1, 2, 3, 4].each do |attr|
    ret = yield attr
    puts attr
  end
end

test = acceptor_method do |attr|
  break 'test' if attr == 3
end

puts test

outputs:

1
2
test
bridiver
  • 1,694
  • 12
  • 13