in reply to Hiding, but maintaining variables in user-defined code

Restating this, because there is a bit of confusion of what I want to do, and to put it more in context. Note that I'm thinking more about simplifying the end-user's side as opposed to simplicitiy in the module code at this point. Please note that this is for a personal project, so if it can't be done, I'll figure out something.

An instance of MyPackage will have a function that can be used to pass in numerous coderefs defined by the user. The MyPackage instance will retain a list of these coderefs as an array, but this detail should be unknown to the user. When the user calls a second function on the instance of MyPackage (with no arguments), the function will select a certain coderef from the array (mostly at random), and execute that coderef. So far, so good; this is easy to do.

However, I would like to provide some support functions that work on an instance of MyPackage, some which might need to know which coderef has been used. I know that since the user already knows the instance of MyPackage, they can use that to run this function, but the additional arguments to it can get problematic. From a UI point of view, they should not know about these extra arguments, only because if they call the functions with the wrong arguments, they may mess up the workings of the package.

So conceptually, I'd like it to look like this:

--in MyPackage.pm #!/usr/bin/perl -w package MyPackage; use strict; sub new { my ( $class ) = @_; my $self = {}; bless $self, $class; return $self; } sub execute { my $self = shift; my $coderef = shift; my $s = $self; my $extra_arg = $some_variable; return &$coderef( ); } sub helper { my $self = shift; my $extra_arg = shift; print "in helper\n"; } 1; --in MyTest.pl #!/usr/bin/perl -w use strict; use MyPackage; my $test = MyPackage->new(); $test->execute( sub { print "in the local coderef\n"; helper(); } ); # HERE'S THE RUB

or, in other words, I want the call to "helper" in "execute()" to have arguements filled it for it without the user filling them in for himself, such that "helper" would be called with arguments ($self, $other_arg).

Now that I write it down this way, I'm wondering if I can use @_ to make this work; I know that @_ behaves in some weird ways with subroutines, but I'll take a look at how that happens to see. But it should be noted that the user coderefs, from the user's standpoint, should not be expecting any arguments.

The other option that I could go with is to use eval'd strings instead of coderefs; thus I could catch for the text "helper" and regex the variables that I need into it when the user sets this. The only thing I don't like about this is that you lose compile time syntax checking of the user's code.


Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

Replies are listed 'Best First'.
Re:{2} Hiding, but maintaining variables in user-defined code
by jeroenes (Priest) on May 23, 2001 at 17:49 UTC
    in other words, I want the call to "helper" in "execute()" to have arguements filled it for it without the user filling them in for himself, such that "helper" would be called with arguments ($self, $other_arg).

    This boils down to: MyPackage has to remember the arguments.

    Well, I would write a wrapper for that. Store the args in $self.

    sub execute{ $self = shift; $coderef = shift; if ( @_ ) { $self->args->{$coderef}=\@_ ; #or [$self, @_] }elsif ( ref(my $args = $self->args{$coderef}) eq 'ARRAY') { @_ = @$args; } return &$coderef( @_ ); }
    Hope this helps,

    Jeroen
    "We are not alone"(FZ)

Re: Re: Hiding, but maintaining variables in user-defined code
by Masem (Monsignor) on May 24, 2001 at 17:12 UTC
    To follow up yet again, I did find something that might help, but will lead into a worse dead end.

    That is, if you call a function via the amperstand approach, with no arguements, the current value of @_ is passed along to that function. So in my case:

    $test->execute( sub { print "in the local coderef\n"; &MyPackage::helper; } );
    the value of @_ that helper() sees would be whatever execute() left @_ as, so here, I could easily fill up @_ with $self and any other variables that I wish. However... some of the functions of similar nature to helper that I have planned would also require user-added arguments, and thus this completely breaks down, since specifying any arguements does not pass @_ further.

    I think what I will end up doing is forcing the user to specify "$self->helper", and then remove any variables that would be passed to the help functions from access by the user.

    </CODE>


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
Re: Re: Hiding, but maintaining variables in user-defined code
by Anonymous Monk on May 23, 2001 at 18:53 UTC
    package My; my $self; sub execute { #... $self=$call; $call->(); undef$self; }