Dear Ruby (1): What about Arguments when Inheriting?

With most of my code becoming more and more stateless and functional, I haven’t given up leveraging Ruby’s excellent way of defining declarative APIs and DSL. Ruby is just too good at that.

However, I am missing a crucial tool in Ruby: being able to pass dynamic arguments to the inheritance, exactly the way I can pass arguments to the object constructor. In short, here’s what I would love to have.

class Memo::Render < Render, engine: Render::JSON 
  property :title
  property :body
end

The Render class could then use those additional arguments in its inherited hook, acting as an initialize on the class level.

class Render
  def self.inherited(subclass, options)
    super
    subclass.engine = options[:engine]
  end

  # def self.property(name); end
  # def self.engine=(name);  end
end

This would also work for anonymous classes, of course.

Memo::Render = 
  Class.new( Render, engine: Render::JSON) 

Looks very Ruby-esque, doesn’t it?

The Problem with inherited

Currently, you need to set class variables in the inherited class to configure it.

class Memo::Render < Render
  def self.engine
    Render::JSON 
  end
end

The massive drawback here (a design flaw in Ruby?) is that this override is evaluated too late, after the inherited hook is called. Check out the exemplary inherited method in the superclass Render and how it behaves.

class Render
  def self.engine; end

  def self.inherited(subclass)
    puts subclass        #=> Memo::Render
    puts subclass.engine #=> nil !!!
  end
end

As you can see, even though Memo::Render implements engine, it isn’t evaluated at inherited time, making this hook more or less useless if you want to cleanly initialize and setup a subclass at compile-time.

One solution could be the proposed extension of the hook, however, the complexity of this change is completely unknown to me due to my lack of Ruby core participation.

Advertisements

9 thoughts on “Dear Ruby (1): What about Arguments when Inheriting?

    1. Cool idea, but I guess this will be the same problem: The class body is evaluated _after_ its inherited hook was called. Have you tested it?

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s