Writing 'plugins'


#1

Hi Folks,

I have a Ruby application that I am trying to extend by developing a
plugin architecture. I have things more or less working but there are
still a few rough edges that I want to get rid off.

I have developed a series of classes (on for each class of plugin) so to
write a new Action plugin you start with:

class Action

class Nagios < Action::Base

def initialize( host, pass, debug = false, port=5667, time_out=20 )

where Action::Base defines a set of defaults for “Actions”.

The Application parses a configuration file and to use a new action you
simply define a new entity in the ‘Action’ section:

[actions] {
   Alert: nagios('nagios.auckland.ac.nz', 'xxxxxx')

All this works fine.

What I now want to do at parse time is to check the parameters passed to
the plugin definition, which ultimately get passed to
Action::Nagios.new. For various reasons I don’t want to actually call
‘new’ at parse time. My first attempt was to add a ‘test’ method to the
class which took the same parameters as initialize but just checked
them. Whenever I invoked Action::Nagios.test I got errors about not
being able to access private method ‘test’. I’m not quite sure what it
means but I’m guessing that class (as opposed to module) method can
only be invoked via a receiver. I this correct?

Any suggestions as to the best way to do this. One (inelegant but
simple) method would be to have a global variable which held the app
state (‘parsing’ ‘running’, etc) and then initialize could look at that
and do the right thing depending on the state.

Cheers, Russell


#2

A bit more data:

My first attempt was to add a ‘test’ method to the
class which took the same parameters as initialize but just checked
them. Whenever I invoked Action::Nagios.test I got errors about not
being able to access private method ‘test’.

actual error is:

private method `test’ called for Action::email:Class

when invoked by:

        begin
          eval "test = Action::#{tok}.test(#{parms})"  # known class 

?
rescue SyntaxError, StandardError =>e
error( “bad paramers or unknown action #{tok}: #{e}”)
rest_of_line
@errors = true
end


#3

On Mon, Feb 26, 2007 at 07:36:36AM +0900, Russell F. wrote:

when invoked by:

        begin
          eval "test = Action::#{tok}.test(#{parms})"  # known class 

?
rescue SyntaxError, StandardError =>e
error( “bad paramers or unknown action #{tok}: #{e}”)
rest_of_line
@errors = true
end

Show the full class definition, including the method definition of
‘test’.

It Works For Me [TM]:

irb(main):001:0> module Action
irb(main):002:1> class Email
irb(main):003:2> def self.test
irb(main):004:3> puts “Wibble”
irb(main):005:3> end
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> Action::Email.test
Wibble
=> nil

Note that you don’t necessarily need to use ‘eval’:

irb(main):011:0> klass=Action.const_get(‘Email’)
=> Action::Email
irb(main):012:0> klass.test
Wibble
=> nil