Enumerable.each vs 'for' loops in Ruby

A few days ago I checked the code using the Ruby project roodi, and I received a warning saying "Don't use 'for' loops. Use Enumerable.each instead." I personally do not see any difference between these two versions of cycles, and attributed the problem of choice to issues of personal faith. I asked people in the !ruby group of identi.ca, but the answers were not convincing. Google also did not shed light on this question.

I changed the code to use Enumerable.each, just in case, and put the problem aside. But today I saw the sample code, clearly demonstrates the difference:

loop1 = []
loop2 = []

calls = ["one", "two", "three"]

calls.each do |c|
  loop1 << Proc.new { puts c }
end

for c in calls
  loop2 << Proc.new { puts c }
end

loop1[1].call #=> "two"
loop2[1].call #=> "three"

One link method fits all

Today I've created a universal rails helper to deal with multiple models of a multi-language project in a common way:

def link_to_add(object, args={})
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  link = link_to(t("#{object.last.to_s}.add"),
                 new_polymorphic_path(object, args))
  content_tag :p, link
end

def link_to_edit(object, args={})
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  return '' if object.last.new_record?
  node = object.last.class.to_s.underscore
  link = link_to(t("#{node}.edit"),
                 edit_polymorphic_path(object, args))
  content_tag :p, link
end

def link_to_delete(object)
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  return '' if object.last.new_record?
  node = object.last.class.to_s.underscore
  link = link_to(t("#{node}.delete"), object,
                 :method => :delete,
                 :confirm => t("#{node}.confirm_deletion"))
  content_tag :p, link
end

Now all links to create, edit or delete an instance look nice and intuitive.

I type short

<%= link_to_add :post %>

instead of long

<% if logged_in? %>
<p><%= link_to t('post.add'), new_post_path %></p>
<% end %>

It handles nested routes. Just type

<%= link_to_edit [@post, @comment] %>

instead of

<% if logged_in? %>
<p><%= link_to t('comment.edit'),
               edit_post_comment_path(@post, @comment) %></p>
<% end %>

And my favorite one:

<%= link_to_delete [@post, @comment] %>

instead of

<% if logged_in? %>
<p><%= link_to t('comment.delete'), [@post, @comment],
               :method => :delete,
               :confirm => t('comment.confirm_deletion') %></p>
<% end unless @comment.new_record? %>

How to make ssh-copy-id without a headache

If you, like I today, cannot perform a passwordless login via ssh to a remote linux server after copying a public key to the server with ssh-copy-id command, please check if the key is actually presents among other authorized keys on the server. I found that sometimes it is not.

$ cat .ssh/authorized_keys
The agent has no identities.

To fix the problem just add the -i argument like below:

$ ssh-copy-id -i user@server.tld

How to fix Andre Geokit timeout method error

If you use Geokit plugin in a rails application, and it started to complain about undefined 'timeout=' method, the following command fired from the application root should help:

$ sed -i 's/Geocoders::timeout/Geocoders::request_timeout/' \
         config/initializers/geokit_config.rb

We've made it!

Canadian visas

Today we've made it! 200 miles to Barnaul and back in less than four hours, running up the semi-empty highway like a hound-dog. Only to pick up passports from the Pony Express office. Only to make sure there are Canadian visas in them. Well yes, there are the visas. Along with a booklet for Canadian newcomers.

Rephrasing Kurt Vonnegut, I'd say it all started when we were younger men - twenty-one months ago, 640 breakfasts ago, three cities ago...

Read other articles | Subsribe to RSS updates

Paul Philippov

Paul Philippov
Zarinsk, Altai, Russia
39 years old, married
Linux, Ruby, Photography