TWIL: Ruby's other meaning for <
tl;dr: < can also mean .subclass_of?(Class) in Ruby
I was working with a group of objects and I only wanted items which
returned an ActiveRecord_Relation to have another message
sent. The relation are all a subclass of different models:
Model_x::ActiveRecord_Relation, Model_y::ActiveRecord_Relation,
Model_z::ActiveRecord_Relation, etc.
My first solution:
object.send_message if object.class.to_s.split('::').last == 'ActiveRecord_Relation'which definitely works, but really messy since the class is being converted to a string then comparison operations are done on it. I tried a few more things to get this to work:
1
2
3
4
5
object.class # => Model_x::ActiveRecord_Relation
object.class.is_a?(ActiveRecord) # => false
object.class.is_a?(ActiveRecord::Base) # => false
object.class.is_a?(ActiveRecord_Relation) # => NameError: uninitialized constant ActiveRecord_Relation
object.class.is_a?(Model_x::ActiveRecord_Relation) # => false
But I could never get the evaluation I want, without resorting to string comparisons (hence, the first solution.)
A better programmer showed me a
object.class < ActiveRecord_Relationwhich, I found out in Ruby < can mean:
object.subclass_of?(Class). Mind: blown.
This is probably the best solution since it uses Ruby’s own method to test whether an object is a subclass of another or not.
< is very easy to over look in Ruby code (and VERY hard to Google!)
as it is used in many other places in Ruby, like:
Model < ActiveRecord::Base
which has a very different meaning than .subclass_of?(Class). :-D
Stay spec-ing my friend.