Rails::Generator destroys Namespaces

The cool thing is that Rails’ script/generator script can be invoked via an API call

Rails::Generator::Scripts::Generate.new.run(%w(controller blog), :destination => '/tmp')

so you can create assets in your code, or test the generator.

Where is my JavascriptGenerator?

The bad thing is, that after you used Rails::Generator, you can’t rely on autoloading anymore, at least for classes ending with Generator.

When trying to use my own class JavascriptGenerator (which has nothing to do with Rails at all) I got

JavascriptGenerator::Base.new # NO rails...

Rails::Generator::GeneratorError: Couldn't find 'javascript' generator

which is really annoying. That’s Rails “magic” again (somewhere in rails/generator/…):

class Object
  class << self
    def lookup_missing_generator(class_id)
      if md = /(.+)Generator$/.match(class_id.to_s)
        name = md.captures.first.demodulize.underscore
        Rails::Generator::Base.lookup(name).klass
      else
        const_missing_before_generators(class_id)
      end
    end

    unless respond_to?(:const_missing_before_generators)
      alias_method :const_missing_before_generators, :const_missing
      alias_method :const_missing, :lookup_missing_generator
    end
  end
end

That’s a typical example how Rails assumes things automatically that you don’t expect.

I personally think that extending Object should be allowed to non-magicians only.

Advertisements

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s