Hacker News new | past | comments | ask | show | jobs | submit login
Ampex - concise readable Ruby blocks (cirw.in)
45 points by samstokes on May 21, 2012 | hide | past | favorite | 17 comments



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.


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.


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.


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.


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]


Yes... which is exactly what the author said. Now try using a method that takes a parameter or chained method calls.


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.


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

  [* _ 2]
becomes

  (lambda (x) (* x 2))


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


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 )


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


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.


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


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


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) }


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.


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




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: