# GemPlugin 0.1 -- A Mongrel Spinoff

**URL:** <https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185>\
**Category:** Ruby\
**Created:** [March 6, 2006, 7:23am UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185 "2006-03-06T07:23:37Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 6, 2006, 7:23am UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/1 "2006-03-06T07:23:37Z")

</div>

Hello folks,

Well I spent the weekend working on the Mongrel  
([http://mongrel.rubyforge.org](http://mongrel.rubyforge.org)) plugin system, and actually ended up  
cracking  
it out into a separate sub-project and releasing it under Ruby or LGPL.

The GemPlugin project is a dynamic plugin system that uses RubyGems to  
create, manage, and load plugins. It’s used in Mongrel to allow others  
to  
create commands for people to use without having to be a part of the  
Mongrel  
project. Other systems could use it no problem and it doesn’t depend on  
any  
Mongrel code.

The stuff is kind of funky, but take a look at:

[http://mongrel.rubyforge.org/gem\_plugin\_rdoc/](http://mongrel.rubyforge.org/gem_plugin_rdoc/)

For more information.

== Quick Usage

Plugin Authors do this:

class Snazzy \< GemPlugin::Plugin “/commands”  
…  
end

Then place this code in a file they will have RubyGems autorequire (I  
use  
lib/init.rb).

Next they need to add the following to whatever Rakefile code you use to  
create your gem:

spec.add\_dependency(‘gem\_plugin’, ‘\>= 0.1’)  
spec.add\_dependency(‘theapp’, ‘\>= 0.1’)  
spec.autorequire = ‘init.rb’

Plugin Users do this:

$ gem install snazzy\_plugin

System Implementers then setup their system to do this:

GemPlugin::Manager.instance.load “theapp” =\> GemPlugin::INCLUDE  
plug = GemPlugin::Manager.instance.create(“/commands/snazzy”)

And everyone is happy. Read the docs for more information.

== Future Directions

There is already a sample plugin available named mongrel\_status which  
people  
can check out as an example:

[http://rubyforge.org/frs/download.php/9029/mongrel\_status-0.1.tgz](http://rubyforge.org/frs/download.php/9029/mongrel_status-0.1.tgz)

Or just:

$ gem install mongrel\_status

Enjoy! And feedback is welcome.

Zed A. Shaw

> **[Zed A. shaw](https://zedshaw.com/)**
>
> Personal essays and writings by Zed A. Shaw.

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 6, 2006, 2:21pm UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/2 "2006-03-06T14:21:25Z")

</div>

On 3/6/06, Zed S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

Hey, Zed. this looks pretty interesting. Just a few points that I think  
will require a pretty quick rework:

> == Quick Usage
> 
> Plugin Authors do this:
> 
> class Snazzy \< GemPlugin::Plugin “/commands”  
> …  
> end
> 
> Then place this code in a file they will have RubyGems autorequire (I  
> use lib/init.rb).

> Next they need to add the following to whatever Rakefile code you use to  
> create your gem:
> 
> spec.add\_dependency(‘gem\_plugin’, ‘\>= 0.1’)  
> spec.add\_dependency(‘theapp’, ‘\>= 0.1’)  
> spec.autorequire = ‘init.rb’

The #autorequire is deprecated at this point and is not recommended in  
any way. RubyGems still supports it, but I believe that the next version  
will be spouting some warnings at people who use autorequire in building  
their gems. Since you’re using a secondary call to do the load, you can  
mandate that lib/init.rb is the file to load and have your loader do the  
require yourself.

> System Implementers then setup their system to do this:
> 
> GemPlugin::Manager.instance.load “theapp” =\> GemPlugin::INCLUDE  
> plug = GemPlugin::Manager.instance.create(“/commands/snazzy”)

This also seems like you’re using Singleton. I think you should be able  
to do this such that you can drop the call to Manager.instance if you  
put your load/create etc. as transparent reflections to an instance. I’m  
not sure that I did it in the most optimal way in MIME::Types 1.15 that  
I released recently, but I had changed MIME::Types from a module to a  
class and implemented it such that it was more or less transparent to  
the user. You should be able to do it with:

class GemPlugin::Manager  
class \<\< self  
private :new

```
  def method_missing(m, *a, &b)
    @ __me__ ||= self.new
    @ __me__. __send__ (m, *a, &b)
  end
end

```

end

Then it would simply become:

GemPlugin::Manager.load “theapp” =\> GemPlugin::INCLUDE  
plug = GemPlugin::Manager.create(“/commands/snazzy”)

-austin

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 6, 2006, 8:02pm UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/3 "2006-03-06T20:02:16Z")

</div>

On Mon, Mar 06, 2006 at 10:20:38PM +0900, Austin Z. wrote:

> On 3/6/06, Zed S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> Hey, Zed. this looks pretty interesting. Just a few points that I think  
> will require a pretty quick rework:

\> The #autorequire is deprecated at this point and is not recommended in \> any way. RubyGems still supports it, but I believe that the next version \> will be spouting some warnings at people who use autorequire in building \> their gems. Since you're using a secondary call to do the load, you can \> mandate that lib/init.rb is the file to load and have your loader do the \> require yourself. \> Man that just sucks. I'll have to think about this, but off the top of my head doing a require of init.rb won't work. I'll have to \_\_FILE\_\_ crap and re-implement the autorequire code.

Maybe I can chat with the rubygems folks and get it put back in. It  
really makes these plugins work perfectly with minimal effort.

> class and implemented it such that it was more or less transparent to  
> end  
> end

I’ll play with this, I agree that the instance stuff is really annoying.  
I also don’t like the include/exclude stuff and will probably change  
that out for something more succinct.

Zed A. Shaw

> **[Zed A. shaw](https://zedshaw.com/)**
>
> Personal essays and writings by Zed A. Shaw.

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 6, 2006, 8:54pm UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/4 "2006-03-06T20:54:08Z")

</div>

On 3/6/06, Austin Z. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > spec.autorequire = ‘init.rb’
> 
> The #autorequire is deprecated at this point and is not recommended in  
> any way. RubyGems still supports it, but I believe that the next version  
> will be spouting some warnings at people who use autorequire in building  
> their gems. Since you’re using a secondary call to do the load, you can  
> mandate that lib/init.rb is the file to load and have your loader do the  
> require yourself.

Maybe I misunderstood this, but I thought “require\_gem {gem-name}”  
used the autorequire attribute to know which file from the gem to  
load. Is that correct? If so, what will happen to require\_gem when  
autorequire goes away?

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 6, 2006, 11:56pm UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/5 "2006-03-06T23:56:58Z")

</div>

Mark V. wrote:

> On 3/6/06, Austin Z. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > > spec.autorequire = ‘init.rb’
> > 
> > The #autorequire is deprecated at this point and is not recommended in  
> > any way. RubyGems still supports it, but I believe that the next version  
> > will be spouting some warnings at people who use autorequire in building  
> > their gems. Since you’re using a secondary call to do the load, you can  
> > mandate that lib/init.rb is the file to load and have your loader do the  
> > require yourself.
> 
> Maybe I misunderstood this, but I thought “require\_gem {gem-name}”  
> used the autorequire attribute to know which file from the gem to  
> load. Is that correct? If so, what will happen to require\_gem when  
> autorequire goes away?

The preferred way of requiring files is to use a plain require. Unless  
something tricky is going on, this will work with both gem and non-gem  
installed software (assuming you load rubygems beforehand if you are  
using gem installs).

The require\_gem is really only needed if you want a particular version  
of gem installed, in which case you just _add_ the require\_gem statement  
in a nice, centrally controlled location in your code (because you don’t  
want to spread version dependencies throughout your code base), and do  
the normal requires.

This is probably with an example:

If you want you use the foo file in the foobar gem, just do whereever  
needed in your code base:

require ‘foo’

(you may need to require rubygems if your system doesn’t make that  
automatic).

If you want to make sure you use version 3.1.4 of the gem foobar, then  
in one central location put:

require\_gem ‘foobar’, ‘= 3.1.4’

And whereever you need the foo file, write:

require ‘foo’

Require\_gem is a mix of two concepts, the specifying of the _gem_  
version, and the requiring of a specific (autorequire) file. This  
conceptual confusion has caused several subtle bugs in the gems software  
over time.

The autorequire feature is a holdever from the days when regular  
requires didn’t work in rubygems. It avoided the need to do a  
require\_gem _and_ a regular require. Since the regular require is all  
that is needed today, autorequire is a holdover from the past.

I haven’t looked at Zed’s issues in detail yet, so I can’t comment on  
his use in the pluggin system.

–  
– Jim W.

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 7, 2006, 12:49pm UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/6 "2006-03-07T12:49:43Z")

</div>

On 3/6/06, Jim W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > require yourself.
> 
> require ‘foo’

The problem I have with this is that maybe all I know is that I want  
to use the foobar gem in my code. How am I supposed to know that the  
main file I should require is foo.rb? Maybe the main file of each gem  
should always have the same name as the gem.

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 8, 2006, 12:08am UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/7 "2006-03-08T00:08:42Z")

</div>

Mark V. wrote:

> On 3/6/06, Jim W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > > > require yourself.
> > 
> > require ‘foo’
> 
> The problem I have with this is that maybe all I know is that I want  
> to use the foobar gem in my code. How am I supposed to know that the  
> main file I should require is foo.rb? Maybe the main file of each gem  
> should always have the same name as the gem.

I suggest specifying standard practices when creating plugins. Naming  
the main include the same as the gem name is one possiblity. Or naming  
the main include “GEMNAME/init.rb”. Just pick a standard and make it  
the standard for defining plugins.

–  
– Jim W.

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 8, 2006, 12:29am UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/8 "2006-03-08T00:29:33Z")

</div>

On 3/7/06, Jim W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > should always have the same name as the gem.
> 
> I suggest specifying standard practices when creating plugins. Naming  
> the main include the same as the gem name is one possiblity. Or naming  
> the main include “GEMNAME/init.rb”. Just pick a standard and make it  
> the standard for defining plugins.

I like your first suggestion best … main include has the same name as  
the gem.

Obviously though, for the gems already out there, when autorequire  
goes away we’ll all have to learn what file we should be requiring.

---

<div class="post-metadata">

**Author:** ![Zed\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/da6949/32.png) [@Zed\_S](https://www.ruby-forum.com/u/Zed_S)\
**Post date:** [March 8, 2006, 1:14am UTC](https://www.ruby-forum.com/t/gemplugin-0-1-a-mongrel-spinoff/77185/9 "2006-03-08T01:14:54Z")

</div>

On 3/7/06, Mark V. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Obviously though, for the gems already out there, when autorequire  
> goes away we’ll all have to learn what file we should be requiring.

Sort of. As far as I know, they’re deprecating it and warning on  
creation in CVS. It won’t affect users any time soon, though. I  
wouldn’t be surprised if a future version released fails to create a  
gem that specifies an autorequire.

As I update my software that I release as gems (far less often than I  
want right now ☹ I am removing the autorequire.

It is my understanding as well that #require\_gem itself will be  
deprecated in favour of something like #activate\_gem.

-austin
