Here in a few minutes I want to show you that ruby lambdas are smart and that they have shorthand notation.

Okey, consider the following simple array of hashes m :

irb(main):034:0> require 'awesome_print'
=> true
irb(main):041:0> m = [ ["value_1", "value_2"], ["value_3", "value_4"]]
=> [["value_1", "value_2"], ["value_3", "value_4"]]
irb(main):043:0> ap m
    [0] [
        [0] "value_1",
        [1] "value_2"
    [1] [
        [0] "value_3",
        [1] "value_4"
=> nil

And our task here is of extracting “second” values to a new array. Simply, you know that it could be done with ruby’s map function :

irb(main):044:0> { |item| item[1] }
=> ["value_2", "value_4"]

Nice, we’ve done what we wanted. But can it be more simplier with shorthand notation?


Ampersand ruby notation(ampersand colon/pretzel colon). Since Ruby 1.9 a new instance method Symbol#to_proc was added. It causes the object yielded to the block to have the method named by the symbol to be invoked on it. So, here is an example of how it used :

(1..3).collect(&:to_s)  #=> ["1", "2", "3"]

And it seems that yes! But meanwhile where is no method second for Arrays

NoMethodError: undefined method `second' for ["value_1", "value_2"]:Array
        from (irb):45:in `map'
        from (irb):45
        from C:/Ruby193/bin/irb:12:in `<main>'
=> ["value_1", "value_3"]

Okey, you’ve remembered Array::at/1 method? We can call it on each item - Meanwhile it can’t be used since :second and :first are symbols and there are no possible variants to pass additional parameter with value 1.

Ok you can extend default to_proc function to take care of multiparameter functions

class Array
  def to_proc
    lambda { |o| o.__send__(*self) }
# and use it the following way
m &[:at, 0]

To conclude, it could be useful to use shorthand notation for calling some methods ( &:to_s, map_obj.inject(0,&:+) ).

But it seems that multiparameter functions should not be used the same way. Just use old explicit notation (use { i i[1] } ).


In comparison, Perl has nice contextual dependent variable $_ or @_ :

my @squares = map { $_ * $_ } @numbers;
# And yes, you can write something like this :
my @res = map { @_[0] * @_[1] } @values_to_product;

I guess, this perl code is simple as it can be. As long as you have some experience in Perl.

Ruby also has $_ or @_ symbols but they used somewhat differently.

And every direct rewrite attempt for perl code will result on snippets similar that you’ve see at the top.