hoodwink.d enhanced
RSS
2.0
XHTML
1.0

RedHanded

Wonder of the When-Be-Splat #

by why in bits

Well, okay, yes, we already know Ruby is expressive. And, if I know you, you’ll see a drop of awesomeness in:

 BOARD_MEMBERS = ['Jan', 'Julie', 'Archie', 'Stewick']
 HISTORIANS = ['Braith', 'Dewey', 'Eduardo']

 case name
 when *BOARD_MEMBERS
   "You're on the board!  A congratulations is in order." 
 when *HISTORIANS
   "You are busy chronicling every deft play." 
 end

I was refactoring a parser and it occured to me that I could just do a when *tokens.keys at one point. Ruby treats it just like a list of conditions. Consider Olympic ice dancing out-graced!

Addendum: I’m just gonna log a few of the other discoveries implied here, just to prove how handily this waxes if..include?’s sorry snout.

 case name when "Arthur", *BOARD_MEMBERS
   "Either you are a board member... or you are Arthur." 
 end

 case name when *BOARD_MEMBERS|HISTORIANS
   "We welcome you all to the First International
    Symposium of Board Members and Historians Alike." 
 end
said on 23 Feb 2006 at 18:46

Say goodbye to include?, case. She wasn’t expressive enough.

said on 23 Feb 2006 at 18:51

That’s beautiful! It communicated to me on three different levels! :-)

M.T.

said on 23 Feb 2006 at 18:57

That is nicely expressive.. but why does it work?

said on 23 Feb 2006 at 19:02

Now thats aesthetics even a designer can love. :-)

said on 23 Feb 2006 at 20:22

Ruby’s case has a lot of goodness, but I never knew.

said on 23 Feb 2006 at 20:28

Beauti-tastic.

said on 24 Feb 2006 at 00:04

That’s cool, but, as a newbie, I don’t see what it going on under the covers. Can someone explain it? Is this some kind of regexp matching?

Thanks!

said on 24 Feb 2006 at 00:05

humdrum: In times past, the splat has been used to pitch an array into a method as the method arguments:

 args = ["/tmp/a-gust-of-wind.txt", "w+"]
 open(*args) { |f| f << "..wchhoooo..." }

More recently, the splat is now widely used in place of to_a.

 animals = [:hound, :hawk]
 gopher = :gopher
 tigers = [:blue_tiger, :fierce_tiger]

 >> animals + [*gopher]
 => [:hound, :hawk, :gopher]
 >> animals + [*tigers]
 => [:hound, :hawk, :blue_tiger, :fierce_tiger]

So, juxtapose this with Ruby’s when statement which can take multiple conditions and you’ve got it.

 case obj
 when String, IO
   YAML.load obj
 else
   obj
 end
said on 24 Feb 2006 at 03:21

Very nice, you learn something new every day!

By the way, you left off a ’ in front of Julie.

Thanks for the tip!

said on 24 Feb 2006 at 08:46

JACKASS = ['phentermine']
case name
 when *JACKASS
   puts "You're a jackass spammer" 
 else 
   puts "Nothing to see here, move along" 
end

said on 24 Feb 2006 at 09:09

That was really awesome why. You never cease to amaze me!!!

said on 24 Feb 2006 at 15:45

Check. Sorry comments were defunct.

said on 24 Feb 2006 at 16:38

This should be a haiku, but I didn’t have time. With all the deep hacking and evil going on lately, I wonder if we’ve been distracted from the simple beauty of Ruby.

Cherry blossoms.

said on 24 Feb 2006 at 20:00

It feels all pattern-match-y :)

said on 24 Feb 2006 at 22:43

“case name when” doesn’t feel all fuzzy inside, shouldn’t “when” be “is” for the first line? :p maybe im getting spoiled with all the english-simulating syntax otherwise around :p :p

said on 25 Feb 2006 at 03:47

This only works with Ruby 1.9, right?

said on 25 Feb 2006 at 06:22

A programming language with a sane syntax? Will the the wonders this world has ever end!

said on 25 Feb 2006 at 07:17

tilman:No, it works on Ruby 1.8.4, not sure about Ruby 1.8.2 though.

a=[1,2,3,4,4]

a.zip([a]) => [[1, [1, 2, 3, 4, 4]], [2, nil], [3, nil], [4, nil], [4, nil]]

a.zip([*a]) => [[1, 1], [2, 2], [3, 3], [4, 4], [4, 4]]

a.zip(*[a]) => [[1, 1], [2, 2], [3, 3], [4, 4], [4, 4]]

a.zip(a) => [[1, 1], [2, 2], [3, 3], [4, 4], [4, 4]]

said on 25 Feb 2006 at 13:00

tilman: It works fine in 1.8.2 as well.


[1, *[2, 3, 4]]
=> [1, 2, 3, 4]

said on 25 Feb 2006 at 17:09

I need to remember this. Might come in useful some time.

said on 26 Feb 2006 at 12:57

Mmh, the first example in the article doesn’t work for me on Ruby 1.8.4 :/

said on 26 Feb 2006 at 13:28

name has to be defined, you cannot copy and paste this code, it won’t work.

said on 27 Feb 2006 at 11:55

I’m not that stupid :P

said on 27 Feb 2006 at 12:48

Works for me. What error are you getting?

said on 27 Feb 2006 at 16:59

tilman Its best to think of the most obvious things first :)

said on 28 Feb 2006 at 11:54

I just realized the result of the case expression was never written to stdout or something :o It works nicely if I add “puts” somewhere ;) tilman—

said on 08 Mar 2006 at 20:14

Destructuring is delicious

Comments are closed for this entry.