Reputation: 97
I have a list of methods who if any of them evaluated to true, I have to trigger an action on the model, in this case it's model audit.
So for example :
def a?
false # in reality this is some code
end
def b?
true # in reality this is some code
end
def c?
true # in reality this is some code
end
Now I can group this into like a parent method like :
def parent_method
a? || b? || c?
end
This will short-circuit the code, and c? will never be executed which is great. I can execute my .audit
method.
But if I wanted to pass in custom message to my .audit
method, and I wanted to have different message for every method how can I do that?
My first though to have a hash with keys being the methods and values being the messages or something along that line. But in that case the short circuiting doesn't work as all methods are evaluated in advance. How can I make this work better and more efficient/elegant?
Upvotes: 1
Views: 271
Reputation: 107142
Instead of true
your method could return a trueish value like a symbol.
def a?
false # in reality this is some code
end
def b?
:b # in reality this is some code
end
def c?
:c # in reality this is some code
end
That you still allow to short-circuit the code in
def parent_method
a? || b? || c?
end
But now parent_method
will not only return true
or false
but it would return a symbol that your allow returning a message that might be stored in a hash:
key = parent_method
audit(key) if key
Upvotes: 1
Reputation: 211740
You can always break these out into a simple array if you're not passing in any arguments. A minimal example looks like:
TESTS = [ :a?, :b?, :c? ]
def parent_method
failed = TESTS.find do |test|
!send(test)
end
if (failed)
# The failed variable contains the name of the method that failed
# to return `true`. Do whatever you need to do here.
errors << "Test #{failed} returned false!"
false
else
true
end
end
Upvotes: 1
Reputation: 114248
if I wanted to pass in custom message to my
.audit
method, and I wanted to have different message for every method how can I do that?
You could use a case
expression:
case
when a? then audit(:a)
when b? then audit(:b)
when c? then audit(:c)
end
Upvotes: 0