I don't know whether to post this as a request for wisdom or as a meditation. I chose for the first because it has a question at the end.

Anyway. I'm writing an chatbot. My design is modular: The bot has a connnection (aim/jabber/irc), a config, a brain, a scheduler, events, etc. All based on plugins so I can change parts while it is running.

The problem is that connections are callback based, and each callback only gets the connection object passed to it.

But the brain and the config need to be accessed from the callbacks.

The naive solution is to use globals, but I want to be able to use a test and a production bot at the same time. The other naive solution is to inherit the ChatBot class from Net::OSCAR (which is what I'm using for AIM) and stick the other objects into it. But that makes it hard to have both AIM and Jabber connections at the same time.

Hence I came up with Class::Bundle. The code is not really important here, if someone's interested let me know and I'll post it.

Class::Bundle is to be used as a base class.

package ChatBot; use base qw/Class::Bundle/; use ChatBot::Config; use ChatBot::Brain; use ChatBot::Logger; # exports logger() ... use Net::OSCAR; sub new { my($class, $name) = @_; my $self = bless { config => ChatBot::Config->new , brain => ChatBot::Brain->new , ... , oscar => Net::OSCAR->new } => ref($class) || $class; $self->bundle($name); # note 1) $self->inject('logger'); # note 2) }

  1. the bundle() method looks at $self and extracts all blessed members. It then goes and injects accessors for all members and the parent into each others namespaces;
  2. the inject() method injects the 'logger' method from the parent namespace into the child namespaces;

So, now the im_in() callback from Net::OSCAR gets the connection object ($oscar) passed to it and I can find my config by doing $oscar->config; and my parent node by $oscar->parent; (or  $oscar->whatever_name_I_passed_to_new();) etc.

This means that Class::Bundle is effectively grouping unrelated classes into a cooperating bundle.

Now, for the promised question(s):


In reply to Bundling unrelated classes by redlemon

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.