-
-
Save dkubb/1130086 to your computer and use it in GitHub Desktop.
require 'rubygems' | |
require 'backports' # aliases Proc#=== to Proc#call | |
rs = (0..10000).to_a.sample(30) | |
rs.each do |r| | |
case r | |
when lambda { |n| n.zero? } then puts "#{r} is zero" | |
when lambda { |n| (n % 5).zero? } then puts "#{r} is fiven" | |
when lambda { |n| (n % 4).zero? } then puts "#{r} is fourven" | |
when lambda { |n| (n % 3).zero? } then puts "#{r} is threeven" | |
when lambda { |n| n.even? } then puts "#{r} is even" | |
when lambda { |n| n.odd? } then puts "#{r} is odd" | |
else | |
raise 'unpossible' | |
end | |
end |
I did not realize this about 1.9. That is a huge deal despite being such a small change. A lot of code that might otherwise have been considered "hacky" becomes idiomatic.
That is hot. Nice find, Dan.
@avdi me either. I was surprised when I came across this code. Even though the 1.9 only syntax is going to take some getting used to, it looks pretty natural and will certainly clean up some cases, like you say.
That's beautiful, and ridiculously powerful.
<3
Very nice. Had been meaning to test if 1.9 did this with ===. If your subject responds to all predicates, you can also have fun with 1.9's Symbol#to_proc: https://gist.github.com/1130320
Proc#call
as #===
is a wonderful addition, but this is a terrible example. I hope I never see someone actually do this.
Why such a harsh reaction? Because you should use case
statements' native capabilities if the predicates are defined in the same scope: https://gist.github.com/1132758.
@emmanuel your gist is how I would probably write this in real production code.
I remember times where I've wished to be able to include more complex logic in a case statement, and have it evaluated at runtime, but I'm coming up blank trying to think of a good example. Anyone else have one?
I agree that this opens terrific options for new types of idiomatic Ruby. I would love to see more examples of how people are using this for great justice, but I suspect such examples will be ill-suited to explication in gist form, by virtue of the substance of my complaint.
To be clear, my point is that this specific example should not be emulated. If the predicates are statically defined in the same scope as a case
statement, do the simple thing: use the case
statement as Matz intended :P
...pardon me while I continue turning into a cantankerous old grump...
I'd still very much like to have &:method work in when arg lists. I spent some time trying to hack parse.y over the weekend, actually, to see if I could make it work in some frankenstein-like manner, but my version of bison seemed not to be playing nicely. :(
This is a ruby 1.8 port of @flazz's code from http://flazz.me/predicates-in-ruby-case-statements (see his fork for original 1.9 specific code)