Why return self in an eval'd class definition?

Viewed 74

I have the following code example:

drop_class = eval "class #{self}::LiquidDropClass < Liquid::Drop; self; end"

I understand what it's doing, but I don't understand why self is returned within the class definition. Is this even necessary, or is it an artefact of the eval class definition method?

In this case, methods are added later on to the class.

UPDATE My confusion is around this:

class XYZ:::LiquidDropClass < Liquid::Drop

end

vs

eval "class XYZ::LiquidDropClass < Liquid::Drop; self; end"

I don't need the self in the first example and the class is created fine.

1 Answers

The value of a class (and module) definition body (note that a class definition body is an expression, and thus has a value; in fact, everything in Ruby is an expression and thus has a value, there are no statements) is the value of the last expression evaluated inside the class definition body. If self weren't the last expression inside that particular class definition body, the class definition body would be empty, and thus its value would be nil, i.e. drop_class would be nil.

Before Object#singleton_class was added to the core library, the idiomatic way to get a reference to the singleton class was to open the singleton class and have it evaluate to self, e.g.:

class Object
  def singleton_class; class << self; self end end
end

Note that this particular piece of code, doesn't actually require eval, it could just as well (and probably clearer) be written as (untested):

drop_class = class const_get(to_s)::LiquidDropClass < Liquid::Drop; self end

Actually, in both cases the class can also be retrieved via other means, so assigning it to drop_class (and thus evaluating self) is not strictly necessary.

Related