Hacker News new | past | comments | ask | show | jobs | submit login

I've never really understood the Ruby community's attitude toward for loops. I learned Ruby as my first language and read many blog posts and instructional books that told me to absolutely avoid the for loop. Of course when I started to learn JavaScript and C, I had to figure out their versions of the for loop then, and it made me start wondering why there had been such opposition to something that seemed to be a normal part of the Ruby language. I can understand "idioms" if they have some benefit over non-idiomatic versions, but in a language like Ruby that supposedly embraces TMTOWDI, I can't, for the life of me, figure out why .each is always best.



I don't think using a for loop is "taboo" among Rubyists in general, just for iterating over each element of an array, where Array#each, Array#collect, and Array#inject are preferred. This probably comes from the influence of Lisp and its emphasis on writing code as a series of list operations.

To my mind, anyway, using each/collect/inject expresses intent much more clearly than a for loop. If a clearer approach is available, why not take advantage of it?


I, too, think like that, although Ruby's nomenclature frequently confuses me. Coming from Scheme/Haskell I'm quite at home with 'map', 'filter', and 'fold'.

However, Ruby uses the methods you mention, "collect" and "inject", and these in turn have a few synonyms. And as best I can tell, Ruby's 'filter' variant, 'find' collides with ActiveRecord. What's the general community take on these functions? Which name is commonly used, and how do you do filter in Rails?


> I, too, think like that, although Ruby's nomenclature frequently confuses me.

Most of them come from Smalltalk's Iterable protocol[0]: that's the source for `select:aBlock`, `collect:aBlock`, `inject:thisValue into:binaryBlock` (Smalltalk uses `fold` when there's no starting value, and `inject` as "fold by injecting initial value"), `detect:aBlock` and `reject:aBlock`.

Smalltalk also uses `do:aBlock` where Ruby uses `each`, likely due to `do` being a keyword in Ruby.

Also, `find` is not `filter` (that's `select`, aliased to `find_all`). `find` is also `find` in Haskell[1] (and maps to Smalltalk's `detect`, also useable in Ruby).

> 'find' collides with ActiveRecord

Uh... no, ActiveRecord collides with Enumerable, I'm pretty damn sure Enumerable came first.

> how do you do filter in Rails?

What's wrong with #find? Or #where? Or #find_by_*? Same name, different namespace, different meaning. Kind-of the point.

[0] http://www.gnu.org/software/smalltalk/manual-base/html_node/...

[1] http://hackage.haskell.org/packages/archive/base/latest/doc/...


In Ruby, I always use "map" instead of "collect", partially because it's four fewer letters and partially because its intent is a little more obvious.


I'd say that most Rubyists use #select, whereas #find is a more literate alias that few use outside of AR.


They are not synonyms. Find will only find one result.




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

Search: