From: Alex Young Date: 2007-07-27T20:45:08+09:00 Subject: Re: eval versus load and plugins Rover Rhubarb wrote: > I'm writing a program with a sort of plugin mechanism. Plugins are > basically single ruby files defining classes. It's not exactly a plugin > mechanism because there an only be one plugin used. > > Image the program command being > ruby myApp -plugin plugins/myPlugin.rb > > > I want to load the plugin which defines its own class (which follows a > certain pattern - since there are no interfaces) then instantiates it. > > At the moment I'm using load to load the plugin file. I don't know the > name of the class of the specific plugin, but I assume it has a _global_ > method called "new_plugin" which instantiates it. > > Since I'm using load I can be sure that the latest plugin loaded will > redefine that global method to instantiate the plugin (I can't call it's > constructor directly because, again, I don't know what name the designer > is going to give the plugin class - though I can expect them to follow > the pattern of defining new_plugin) > > Questions: > > 1. I notice that rails uses eval to load the init.rb files of plugins. > What are the advantages disadvantages of this versus using load? > (Note also this thread about using eval or load - both are suggested but > I dont see why we would use eval over load > http://www.ruby-forum.com/topic/55540#new) Not sure off the top of my head. Someone else can probably weigh in here. > 2. Is there some nicer, cleaner way of doing what I'm doing without > having the plugin file define a global method? Make them subclass a base class that you provide, or make them mix in a module that you specify. That gives you the Class#inherited and Module#included callbacks to play with, which strikes me as cleaner than relying on a method override. > 3. Is there a neat way of forcing the plugin to match a certain pattern. > I've seen the "interface" support library, but it seems to be > shoehorning Ruby into a Java paradigm. What would be the rubyful way? > Just calling respond_to? on all of the methods I expect and raising > errors? If the plugin subclasses a base class you specify, you can either check it manually in the callback (which seems a little clumsy to me), or provide all the interface members with: def interface_member raise NotImplementedError end in the base class. The former is probably necessary if you need to sanity check the class before doing anything with it - you can get away with the latter otherwise. HTH -- Alex