0

This is somewhat of an esoteric situation that I am not even sure is possible. I have a method that is called by a lot of methods:

def called_by_a_lot_of_methods
  # Work
end

I am introducing a feature in which the called_by_a_lot_of_methods will do stuff depends on the caller method, and my current solution is to change all these methods to pass their names when calling called_by_a_lot_of_methods:

def some_method
  called_by_a_lot_of_methods(method_name: some_method)
end

Or, alternatively:

def some_method
  called_by_a_lot_of_methods(method_name: __method__)
end

But this is becoming tedious, and I was wondering if I can give the method_name parameter a default value:

def called_by_a_lot_of_methods(method_name: __method__)
  # Work
end

This does not work because __method__ evaluates immediately giving called_by_a_lot_of_methods, which is obviously not what I want. The question then is, is there a way in Ruby to defer the evaluation of the argument until a useful time when I know it should give the correct result, which is the outer caller method? Thus saving me from having to pass the argument everywhere?

anothermh
  • 9,815
  • 3
  • 33
  • 52
n_x_l
  • 1,552
  • 3
  • 17
  • 34
  • 4
    This seems like an [xy problem](https://meta.stackexchange.com/a/233676/399876). Why should a function change its behavior based on where it's called from? This is too strongly coupled and strikes me like a giant switch statement in the function. The solution to such problems is usually to write different functions for each behavior you need. If this results in code duplication, write helper functions for all the parts that are generic. More details about the actual use case would be helpful here. Thanks. – ggorlen Mar 27 '20 at 00:13
  • https://stackoverflow.com/a/15098459/3784008, so something like `called_by_a_lot_of_methods(method_name: caller_locations(1,1)[0].label)`, but I completely agree with @ggorlen that this is the wrong way to do it. Methods should be short, simple, and singular in purpose, and I'd want to understand the actual code behind your problem to offer a better solution than this. Also no guarantee that `caller_locations` is always going to work the way you expect. – anothermh Mar 27 '20 at 00:24
  • 2
    It's a violation of [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) ... the method should not need to know where it's getting called from. If the caller needs to inject some behavior, you can make the method accept a block. – max pleaner Mar 27 '20 at 00:32
  • I understand all your concerns, I am working with somewhat of a legacy systems, and all caveats are assumed, such as knowing that the `caller_locations` won't always be correct (for instance a two level call stack). I was just curious if this is doable. – n_x_l Mar 27 '20 at 01:04

0 Answers0