[フレーム]
Last Updated: February 25, 2016
·
3.717K
· alxndr

lambdas in ruby case (switch)

A little class that has code and message attributes (ignore the bizarre HTML link, I can't prevent Markdown from putting it in?):

class Response
 attr :code, :message
 def initialize(c, m)
 @code, @message = c, m # the <a> should not be here...
 end
end

...and a method that analyzes those attributes. The interesting part is in a case, where two of the whens use some local methods that return lambdas:

def analyze(resp)
 def code_is(c)
 lambda { |r| r.code == c }
 end

 def message_is(m)
 lambda { |r| r.message == m }
 end

 case resp
 when code_is(200)
 "we are good to go"
 when message_is("Not Modified")
 "not a 200, but it's okay anyway"
 else
 "uh oh, we got a problem... #{resp.inspect}"
 end
end

Now let's see it in action:

response = Response.new(200, "whatever")
puts "first up", analyze(response), ""

response = Response.new(300, "Not Modified")
puts "next", analyze(response), ""

response = Response.new(404, "No Way")
puts "and finally", analyze(response)

This works because the whens do a ===, which lambdas/Procs use to run themselves.

More: http://www.aimred.com/news/developers/2008/08/14/unlocking_the_power_of_case_equality_proc/

3 Responses
Add your response

Another way of doing this would be to set constants to lambdas and use them as matchers, such as this:

SUCCESS = ->(response) { response.code == 200 }
NOT_MODIFIED =->(response) { response.message == 'Not Modified' }

case response
when SUCCESS then "we are good to go"
when NOT_MODIFIED then "not a 200, but it's okay anyway"
else
 "uh oh, we got a problem... #{response.inspect}"
end
over 1 year ago ·

@brickattack Yeah, very nice!

over 1 year ago ·

So the point is you don't need lambda.call because the === operator (which is what gets called by the case statement under the hood) invokes that on the lambda by default?

over 1 year ago ·

AltStyle によって変換されたページ (->オリジナル) /