Posted: Mon Feb 13, 2006 10:59 am Post subject: RiveScript -- Using Inline Objects
To any of you who use Chatbot::RiveScript (CPAN Link) for your bot's brain, this is something that might interest you. In version 0.04 of the module, support was added for declaring object codes inside your RiveScript reply files with the >object label.
However, sometimes there'd be some objects which just wouldn't load in this fashion, and I was totally clueless as to what the problem was. But I've figured it out.
Post from AiChaos Forum:
_____________________________
I've figured out what is probably THE problem that was making RiveScript objects not work when declared in-line:
The RS object's code was evaluated within Chatbot::RiveScript, so it did NOT have access to your main program's loaded modules or variables.
So for example, if you have an object that uses LWP::Simple, you have to explicitly declare "use LWP::Simple;" inside of your object's code, because Chatbot::RiveScript does not load that module by default, and, even if your main program loaded the module, the object's code is a subroutine of Chatbot::RiveScript and cannot use that instance of the module.
I've just tested this on my bot. The last time I tried turning every object into inline RS code, some objects wouldn't work. Well now that I've found the key, all my objects work.
I'll include a section on this in the POD of the next module release, but for now, here are the basic tips:
1) Explicitly load every module your object will use within the object. The only modules RiveScript's module uses is strict and warnings, so these don't have to be (re)loaded.
2) Any references to global variables within your main program must have an "main::" before them (i.e. "$main::hashref->{key}")
3) Any references to subroutines of your main program must have "main::" before them (i.e. "&main::reload()")
Here's an example from my Google search object, with the things highlighted that needed to be added:
Quote:
> object google
my ($method,$msg) = @_;
my $key = $main::aiden->{config}->{google};
if (length $key == 0) {
# A valid key is required for this command.
return "This command requires you to obtain a Google Search Key. You "
. "can get one at http://www.google.com/apis/ . Install the "
. "Google key by opening settings.cfg in a text editor and "
. "setting the variable \"googlekey\" and insert the new "
. "key as its value.";
}
use SOAP::Lite;
my $google = SOAP::Lite->service ('file:./lib/GoogleSearch.wsdl');
my $query = $msg;
my $result = $google->doGoogleSearch($key, $query, 0, 5, 'false', '', 'false', '', 'latin1', 'latin1');
my $reply;
foreach my $element (@{$result->{resultElements}}) {
$reply .= "$element->{title}\n"
. "$element->{URL}\n\n";
}