index.md (2685B)
1 --- 2 title: "Convert a Ruby Method to a Lambda" 3 date: 2011-04-26T00:00:00+00:00 4 draft: false 5 canonical_url: https://www.viget.com/articles/convert-ruby-method-to-lambda/ 6 --- 7 8 Last week I tweeted: 9 10 > Convert a method to a lambda in Ruby: lambda(&method(:events_path)). 11 > OR JUST USE JAVASCRIPT. 12 13 It might not be clear what I was talking about or why it would be 14 useful, so allow me to elaborate. Say you've got the following bit of 15 Javascript: 16 17 ```javascript 18 var ytmnd = function() { 19 alert("you're the man now " + (arguments[0] || "dog")); 20 }; 21 ``` 22 23 Calling `ytmnd()` gets us `you're the man now dog`, while 24 `ytmnd("david")` yields `you're the man now david`. Calling simply 25 `ytmnd` gives us a reference to the function that we're free to pass 26 around and call at a later time. Consider now the following Ruby code: 27 28 ```ruby 29 def ytmnd(name = "dog") 30 puts "you're the man now #{name}" 31 end 32 ``` 33 34 First, aren't default argument values and string interpolation awesome? 35 Love you, Ruby. Just as with our Javascript function, calling `ytmnd()` 36 prints "you're the man now dog", and `ytmnd("david")` also works as 37 you'd expect. But. BUT. Running `ytmnd` returns *not* a reference to the 38 method, but rather calls it outright, leaving you with nothing but Sean 39 Connery's timeless words. 40 41 To duplicate Javascript's behavior, you can convert the method to a 42 lambda with `sean = lambda(&method(:ytmnd))`. Now you've got something 43 you can call with `sean.call` or `sean.call("david")` and pass around 44 with `sean`. 45 46 BUT WAIT. Everything in Ruby is an object, even methods. And as it turns 47 out, a method object behaves very much like a lambda. So rather than 48 saying `sean = lambda(&method(:ytmnd))`, you can simply say 49 `sean = method(:ytmnd)`, and then call it as if it were a lambda with 50 `.call` or `[]`. Big ups to 51 [Justin](https://www.viget.com/about/team/jmarney/) for that knowledge 52 bomb. 53 54 ### WHOOOO CARES 55 56 All contrivances aside, there are real-life instances where you'd want 57 to take advantage of this language feature. Imagine a Rails partial that 58 renders a list of filtered links for a given model. How would you tell 59 the partial where to send the links? You could pass in a string and use 60 old-school `:action` and `:controller` params or use `eval` (yuck). You 61 could create the lambda the long way with something like 62 `:base_url => lambda { |*args| articles_path(*args) }`, but using 63 `method(:articles_path)` accomplishes the same thing with much less line 64 noise. 65 66 I'm not sure it would have ever occurred to me to do something like this 67 before I got into Javascript. Just goes to show that if you want to get 68 better as a Rubyist, a great place to start is with a different language 69 entirely.