Consulting. Training. Development.

Define everything you want in Ruby

Have you ever thought about which symbols Ruby method name can contain?

1
2
3
4
5
class Wat
  define_method(', .;') { puts 'WAT' }
end

Wat.new.public_send(', .;') # => 'WAT'

Right. It works in Ruby and is even used in ActiveModel codebase as column names in databases can have spaces for instance. So if column name is “total price” you can call this method which was defined by ActiveModel for you as:

1
user.public_send('total price') # WORKS!

And you definetely can’t call it as

1
user.total price

because, you know, it’s impossible for parser to understand this code as a method call.

Actually I’ve discovered this feature when geocoder gem broke our application. Look at the following diff:

1
2
3
4
5
6
 def self.response_attributes
-      %w[place_id, osm_type, osm_id, boundingbox, license,
-         polygonpoints, display_name, class, type, stadium, suburb]
+      %w[place_id osm_type osm_id boundingbox license
+         polygonpoints display_name class type stadium suburb]
 end

Before this was fixed as you can see there was a typo in defining response_attributes array (which is used to define methods with corresponding names). Yeah, extra commas (note: you don’t need to separate items in array if you use %w[] syntax). But it worked OK because we can define methods with commas and other stuff. And thanks to that typo class method wasn’t redefined in our code. Fortunately it’s already fixed.

Comments