

Ampex - concise readable Ruby blocks - samstokes
http://cirw.in/blog/ampex

======
stuffihavemade
I don't see the point of this. How is

    
    
      [10, 11, 12].map(&X.to_s(16))
    

more readable than

    
    
      [10, 11, 12].map({|x| x.to_s(16)})
    

? The motivation behind this (less temporary variables) is a non issue to me
since the scope of such variables is tiny. In addition, this makes code non
idiomatic and harder to read for anyone who hasn't used this gem, and adds
another dependency to projects.

~~~
cirwin
Consider you have two of these things close together:

    
    
      [10, 11, 12].map{|x| x.to_s(16)}
      [:baz, :bam, :bar].map{|x| x.to_s(16)}
    

At least for me, I tie the 'x's together in my head; so I have to concentrate
to realise that there are two different 'x's.

I've not done any formal research into this, it would be interesting to see
whether there's actually a perceivable difference between the two styles.

~~~
stuffihavemade
I would never stop to think that the x's could be the same. The fact the {}
instead of do syntax is used and the fact that the parameter is called 'x'
instead of something more descriptive tells me that I shouldn't be concerned
with the parameter itself.

------
gary4gar
After reading the article, Discovered that instead of

    
    
      ["1","2","3"].map{|s| s.to_i}
        => [1, 2, 3] 

we can also do

    
    
      ["1","2","3"].map(&:to_i)
        => [1, 2, 3] 
    

This worked for me on Ruby 1.9 out of the box. And I think its an useful
shortcut especially when its part of core ruby language & works WITHOUT using
any external gems.

~~~
esmevane
Also, there's some application for lambdas, here:

    
    
      ruby-1.9.3-p0 :001 > double = -> x { x * 2 }
       => #<Proc:0x000001009236e0@(irb):1 (lambda)> 
      ruby-1.9.3-p0 :002 > double[2]
       => 4 
      ruby-1.9.3-p0 :003 > [1].map(&double)
       => [2]

------
noahlt
Reminds me a lot of Arc's square bracket syntax:

    
    
      [* _ 2]
    

becomes

    
    
      (lambda (x) (* x 2))

~~~
draegtun
Ditto _Whatever-star_ from Perl6 which is more akin to Scala's _underscore_
but using an _asterix_
(<http://perl6advent.wordpress.com/2009/12/19/day-19-whatever/>)

Here's the Ruby examples in perl6 (all work in Rakudo)...

    
    
      [10, 11, 12].map: (* + 87).chr;
    
      @owners.map: *<name>;
    
      "alpha\nbeta\ngamma\n".lines.map: *.uc;
    

NB. A limited version of _Whatever-star_ is also available for perl5 -
<https://metacpan.org/module/Whatever>

------
christianbryant
This is how languages move forward (or backward). Nice, warrants use and test,
but at least people are working to further Ruby. One of the reasons I live on
CPAN (as a non-programmer): What new and _useful_ code will I find today?
Cheers.

------
jes5199
my feeling is: When you are using method_missing hacks to build an object that
watches what methods get called on itself, you will eventually get into
trouble. There are enough things in Ruby that aren't really methods, like the
!= operator, which won't do what you expect, and you will produce very
confusing bugs, because the code will look correct. The hours that I've seen
wasted because people tried to use `x.should != y` in RSpec is enough time to
learn a language that supports hygienic macros.

Writing these libraries is a great way to learn about ruby, but avoid them in
production - there's usually a safer way. (For a simple example of dangerous-
methodmissing-hack verus sane metaprogramming to accomplish the same task,
compare <http://andand.rubyforge.org/> with
<http://api.rubyonrails.org/classes/Object.html#method-i-try> )

------
chucknelson
I actually like having a temporary variable name in the block to help me
follow things, but this will probably appeal to some people.

~~~
snorkel
Agree. The goal ought to be to make code more understanble rather than more
terse. This short example reads fine either way, but when an expert coder puts
this subtle trick in a pile of code noise the replacement developer that has
to fix that code months later curses every line of it.

------
cjensen
I doubt Ampex Corporation (one of the oldest Silicon Valley Area companies)
will be amused by the name of this module.

------
AaronBBrown
I'm curious about the performance overhead of this vs using traditional syntax
with named variables. Looking over the gem, the code is quite terse, but it
depends on method_missing, which is notoriously slow. The danger with an
abstraction like this is that it can make performance problems difficult to
identify since it looks so much like a built-in operator.

I also agree with stuffihavemade in that I don't actually find

    
    
       (&X.method(bar))
    

any more clear than

    
    
       { |x| x.method(bar) }

~~~
cirwin
It's certainly not "free", but as the method_missing calls are all outside of
the loop ((0...1000).map(&X.to_s) calls method_missing only once) the impact
on code is minimal.

I've also found using perftools.rb that it's pretty easy to spot ampex — there
was one place where we were using it in a tight nested loop and removing that
made a measurable difference over tens of thousands of iterations (just as
converting &block parameters to implicit yields makes a measurable
difference); but mostly the causes of slowness in our app have not been this.

------
jph
How about better Ruby syntax? Such as map.foo instead of map { |x| x.foo }

------
danso
Nice. I have to confess to not using the &: syntax enough...maybe this gem
will finally get me into the habit.

