in reply to Re: Variable Name Mistery. Who calls?
in thread Variable Name Mistery. Who calls?

What I want is: I'm working on a module to allow me create objects on the fly (I know there are a bunch of cpan modules that does exactly the same and better, but I was wondering how would that be, and also considered that a good learning experience) The point is that I'm using something like this (On my main class):
sub AUTOLOAD { my $_call = our $AUTOLOAD; $_call =~ s/.*:://; my $self = shift; my $param = shift; ... $self->{$_call} = $_param || return $self->{$_call}; }
So far, so good. But the problem is, that at some point, when I initialize a 'new' object, I define for it a list of available parameters, which will be then used as that object method. So, what I want is to raise a warning when I try to do something like
my $o = Foo->new(); #create new object $o->Available_Param_List(["one", "two"]); #methods that should be avai +lable to $o $o->one('this will work ok'); $o->nope('this should print a warn on saying that nope is not availabl +e for $o');
I want to avoid things like passing the var name to the constructor function or things like that... Thats why I been thinking that *maybe* there was a way to know the name of the variable that called to a package.

Replies are listed 'Best First'.
Re^3: Variable Name Mistery. Who calls?
by ikegami (Patriarch) on Oct 25, 2006 at 19:16 UTC

    The traditional message is

    Can't locate object method "nope" via package "Foo" (perhaps you forgo +t to load "Foo"?) at file.pl line 4.

    Why won't the following suffice?

    Can't locate object method "nope" (perhaps you forgot to specify "nope +" to Available_Param_List) at file.pl line 4.

    Chances are you won't be calling nope more than one time per line, so you'll know exactly which object is giving the error.

    Use Carp's croak to make the message appear to originate from the calling line.

Re^3: Variable Name Mistery. Who calls?
by cephas (Pilgrim) on Oct 25, 2006 at 19:26 UTC
    #!/usr/bin/perl my $o = Foo->new(); $o->available_methods([ qw/one two/]); $o->one("This will work\n"); $o->two("This will work as well\n"); $o->three("This won't work\n"); package Foo; use Carp; my %Objs; sub new { my $self = {}; $Objs{$self} = {}; bless $self, shift; } sub available_methods { my($self,$methods_ref) = @_; $Objs{$self}{methods} = $methods_ref; } sub DESTROY { my $self = shift; delete $Objs{$self}; } sub AUTOLOAD { my $_call = our $AUTOLOAD; $_call =~ s/.*:://; my $self = shift; my $param = shift; if(grep /$_call/,@{ $Objs{$self}{methods} }) { print $param; } else { carp("Couldn't execute $_call\n"); } }
      It's almost there. this is the output I've got: ~$ perl p.pl This will work This will work as well Couldn't execute three at p.pl line 9 And, what I want to achieve is to print (for example) which variable raised that warning. Something like this: Couldn't execute three on $o at p.pl line 9 Perhaps am I asking to much?

        Well, you could use PadWalker's var_name. var_name won't always work, though.

        Before using PadWalker, ask yourself if you really think the tiny bit of extra usefulness to help debug the rare situation where a non-existant function is called more than once in a given statement is really worth the extra work, complexity and maintenance issues of displaying the variable's name (when there might not even be one).

Re^3: Variable Name Mistery. Who calls?
by ysth (Canon) on Oct 26, 2006 at 00:01 UTC
    my $param = shift; ... $self->{$_call} = $_param || return $self->{$_call};
    I assume $param and $_param were supposed to be the same. That's a little obfuscated, and doesn't allow setting parameters to false values. A more typical way to do it is:
    # (after shifting everything but param) if (@_) { return $self->{$_call} = shift; } else { return $self->{$_call}; }