# Writing 'plugins'

**URL:** <https://www.ruby-forum.com/t/writing-plugins/86789>\
**Category:** Ruby\
**Created:** [February 25, 2007, 11:24pm UTC](https://www.ruby-forum.com/t/writing-plugins/86789 "2007-02-25T23:24:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [February 25, 2007, 11:24pm UTC](https://www.ruby-forum.com/t/writing-plugins/86789/1 "2007-02-25T23:24:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [February 25, 2007, 11:36pm UTC](https://www.ruby-forum.com/t/writing-plugins/86789/2 "2007-02-25T23:36:34Z")

</div>

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:📧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

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [February 26, 2007, 7:40am UTC](https://www.ruby-forum.com/t/writing-plugins/86789/3 "2007-02-26T07:40:54Z")

</div>

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
