in reply to Re: Dynamically Creating (and Calling) Object Methods
in thread Dynamically Creating (and Calling) Object Methods

Thanks for the reply. That does make sense. After some googling I tried this approach in BigDB::new()...
# $cmd = "method1" eval { no strict 'refs'; *{'BigDB\::$cmd'} = makeCommandSub($CMDS->{$cmd}); } or die "Can't modify the symbol table: $!";
...but this does not seem to result in a usable $myDB->method1() as I would like. ("Cannot locate method "method1" via package BigDB....")

So next I tried hard-coding the new symbol name like so:

*BigDB::method1 = makeCommandSub(...);
and that works! So I just need to know how to use a string as part of the symbol reference. More clues? :-)

Replies are listed 'Best First'.
Re^3: Dynamically Creating (and Calling) Object Methods
by gaal (Parson) on Jan 07, 2007 at 10:03 UTC
    First, unrelated to your main task: you don't need to say eval {...} or die $!, for several reasons. The first is that if it throws an exception, you can probably use the original exception :) Second, the or there is dangerous unless makeCommandsSub is guaranteed to return a true value; the valuation of an eval is (like any other block of Perl 5) its last evaluated thing. So
    eval { 0 } or die "this dies, but not because of an exception in the i +nner block!";

    Finally, $! is wrong in this case, you need $@ for the exception.

    But to your real question:

    You said 'BigDB\::$cmd'. But because of the single quotes, this creates literally a '$cmd' package in BigDB's symbol table! (Check by printing keys %BigDB::.) The correct code is

    *{"BigDB::$cmd"} = ...

    You probably got the backslash from code that used a variable containing the caller, where it's needed to make Perl not think you're talking about a fully qualified variable:

    *{"$caller\::methodname"} = ...
Re^3: Dynamically Creating (and Calling) Object Methods
by ysth (Canon) on Jan 07, 2007 at 17:57 UTC
    'BigDB\::$cmd' is single-quoted, so creates a method named $cmd in package BigDB\ instead of a method named method1 in package BigDB. Try double quotes (where the backslash becomes harmless though unnecessary).