Forum: Ruby writing 'plugins'

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9528ea68a2efbf9093b1d41f7f269f36?d=identicon&s=25 Russell Fulton (russellf)
on 2007-02-25 23:24
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
9528ea68a2efbf9093b1d41f7f269f36?d=identicon&s=25 Russell Fulton (russellf)
on 2007-02-25 23:36
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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-02-26 07:40
(Received via mailing list)
On Mon, Feb 26, 2007 at 07:36:36AM +0900, Russell Fulton 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
This topic is locked and can not be replied to.