Considering this code:
#!/usr/bin/perl
package p1;
use Data::Dumper;
sub dump_it {
print Dumper @_
}
package p2;
local *foo = *p1::dump_it;
foo('this works');
#local *foo = *p1::dump_it("but this doesn't");
#foo;
I kind of understand, why passing a parameter here can't work, however I think it would be quite practical in some situations. Is there a way to make something similar to the commented-out part function? I would not want to wrap the dump_it in another sub, but directly use a reference.
CodePudding user response:
You can wrap another sub around it, but use goto to prevent it from creating another stack:
sub foo {
@_ = 'use goto';
goto &p1::dump_it
}
CodePudding user response:
You need to create a sub.
sub foo {
p1::dump_it( "wrapped", @_ );
}
But it can be an anonymous one.
local *foo = sub {
p1::dump_it( "wrapped", @_ );
};
Maybe this is more your style:
sub prepend_args {
my $sub = shift;
my @to_prepend = @_;
return sub { $sub->( @to_prepend, @_ ) };
}
local *foo = prepend_args( \&bar, "abc" );
foo( "def" ); # Same as `bar( "abc", "def" );`
See also Hook::LexWrap.
Since you mentioned currying,
sub curry {
my $sub = shift;
return sub {
my $arg1 = shift;
return sub {
my $arg2 = shift;
return $sub->( $arg1, $arg2 );
};
};
}
local *foo = curry( \&bar );
foo( "abc" )->( "def" ); # Same as `bar( "abc", "def" );`
CodePudding user response:
Of course it is
local *foo = *p1::dump_it->("this now does, too!");