hoodwink.d enhanced
RSS
2.0
XHTML
1.0

RedHanded

The Siphoning Splat #

by why in bits

I’m serious about this. The splat is such a wildly devious little asterisk.

>> instruments = {'trombones' => 1, 'clarinets' => 2}       
>> p instruments.to_a
[["trombones", 1], ["clarinets", 2]]
>> p *instruments
["trombones", 1]
["clarinets", 2]

A 2-in-1 combo move! Look at that splat. It’s not just to_a. It called to_a and it siphoned the arguments.

So, Camping has an r method which is for making HTTP responses from scratch. The signature of this method is: r(status, body, headers = {}).

 r(404, 'Not Found', 'X-Powered-By' => 'Camping')

And it has controller objects (descended from Camping::Base) which you run into sometimes. These objects have @status, @headers and @body ivars inside them.

 class Camping::Base
   def to_a
     [@status, @body, @headers]
   end
 end

With the above to_a method, I can now do:

 r(*controller)

Which can be used as a syntax for forwarding HTTP requests.

See, Camping has a technique for making requests inside itself. For example, let’s say we’ve got a Search controller that takes a q variable with search terms in it. And, let’s say we want the front page (the Index controller) to show the results page for a search containing the word “clarinet.”

 class Index < R '/'
   def get
     r *AppName.post(:Search, :env => @env, :input => {:q => "clarinet"})
   end
 end

The splat is Ruby’s pipe for arrays. Put that in your pipe and splat it!

said on 28 Dec 2006 at 23:53

well, interesting. I have always been disconcerted about the splat. It doesn’t seem very intuitive.

said on 28 Dec 2006 at 23:58

This could be used to forward stuff to the 404 handler in Camping, which is a common question.

 module Blog::Controllers
   class Read < '/(\d+)'
     def get(id)
       Post.find(id)
     rescue
       r *Blog.get(:NotFound, @env.REQUEST_URI)
     end
   end
 end
said on 29 Dec 2006 at 02:18

>> cb = "I like chunky bacon" 
=> "I like chunky bacon" 
>> puts *cb
I like chunky bacon
=> nil
>> cb.instance_eval{ def to_a; self.split(" "); end}
=> nil
>> puts *cb
I
like
chunky
bacon
=> nil
said on 29 Dec 2006 at 03:22

Nooo!! The words chunky and bacon should NEVER be split!!

said on 29 Dec 2006 at 04:53

If r takes r(status, body, headers = {}) and Camping::Base#to_a returns [@status, @headers, @body], then surely r(*controller) will end up passing headers to the body param and the body to the headers param?

said on 29 Dec 2006 at 08:10

I have greatly missed entries like this, _why

I guess you’ve been busy with Monkey Starfishies and such?

said on 29 Dec 2006 at 10:53

John: Surely. Thanks!

Danno: Actually, been off harvesting a cheetah-based apple solution. And such.

said on 29 Dec 2006 at 17:32
Not splatting exactly, but currying still. This may be obvious to some, but I just noticed a day ago that you can do:

S = Struct.new(:type, :food)
s = S.new
s.type, s.food = "Chunky", "Bacon" 

I always assumed it wouldn’t apply the attribute= methods on each… but it does! Ruby makes me happy!
said on 29 Dec 2006 at 17:35
Ahh here we go, lets make that post relevant! Same as above but now toss in:

type, food = *s

And since Structs turn to_a into arrays of your properties, splat! It works.
said on 16 Jan 2007 at 09:50

Well but for readability that is da Horror. You are making me a bit freid now.

But it’s Ooooo so cool :D.

11 Jul 2010 at 20:53

* do fancy stuff in your comment.

PREVIEW PANE