[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

eval versus load and plugins

rhubarb

7/27/2007 11:26:00 AM

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-...topic...)

2. Is there some nicer, cleaner way of doing what I'm doing without
having the plugin file define a global method?

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?
--
Posted via http://www.ruby-....

3 Answers

Alex Young

7/27/2007 11:45:00 AM

0

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...)
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

Joel VanderWerf

7/27/2007 5:10:00 PM

0

Rover Rhubarb wrote:
> 2. Is there some nicer, cleaner way of doing what I'm doing without
> having the plugin file define a global method?

You can module_eval the file in the context of a new (anonymous, if you
like) module. Here's one way to do that:

[~/tmp] cat main.rb
require 'script' # http://redshift.sourceforge.n...

plugin_module = Script.load("plugin.rb")

# either:
plugin_class = plugin_module::PluginClass
p plugin_class.new.foo

# or:
plugin_class = plugin_module.get_the_plugin_class
p plugin_class.new.foo

[~/tmp] cat plugin.rb
class PluginClass
def foo
"FOO"
end
end

def get_the_plugin_class # NOT really global -- in module scope
PluginClass
end

[~/tmp] ruby main.rb
"FOO"
"FOO"


--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Giles Bowkett

7/27/2007 7:31:00 PM

0

> > 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...)
> Not sure off the top of my head. Someone else can probably weigh in here.

Here's the code I think you mean:

eval(IO.read(init_path), binding, init_path)

I think the reason it does this is to allow flexible bindings. I
couldn't find "binding" defined in the method anywhere. I really don't
know, so I paraphrased this part of your question and posted it on the
Rails core list.

--
Giles Bowkett

Blog: http://gilesbowkett.bl...
Portfolio: http://www.gilesg...