in reply to Re: The & prototype and code references in scalars.
in thread The & prototype and code references in scalars.

That works! I think I did something else though?

Update: I found the example on the disk image DVD from my old machine;

doit \&{ $codeRef };;

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"I'd rather go naked than blow up my ass"

Replies are listed 'Best First'.
Re^3: The & prototype and code references in scalars.
by shmem (Chancellor) on Feb 17, 2010 at 23:20 UTC

    Another way:

    sub testit{ print 'hi' } sub doit (&) { $_[0]->() } $codeRef = \&testit; doit { &$codeRef };

    update (after BrowserUk's response below) -

    My suggestion adds next to nothing, since wrt to sub stacks, $ref->() is just syntactic sugar for &$ref or vice versa. The notation doit \&{ $subref } seems to be the right thing to do:

    #!/usr/bin/perl use Carp qw(cluck); sub testit{ cluck 'hi',$/ };; sub doit (&) { print $_[0],$/;$_[0]->() };; $codeRef = \&testit;; doit { &$codeRef }; __END__ CODE(0x955737c) hi at coderef.pl line 3 main::testit called at coderef.pl line 6 main::__ANON__() called at coderef.pl line 4 main::doit('CODE(0x955737c)') called at coderef.pl line 6
    #!/usr/bin/perl use Carp qw(cluck); sub testit{ cluck 'hi',$/ };; sub doit (&) { print $_[0],$/;$_[0]->() };; $codeRef = \&testit;; doit \&{ $codeRef }; __END__ CODE(0x9f4c11c) hi at coderef.pl line 3 main::testit() called at coderef.pl line 4 main::doit('CODE(0x9f4c11c)') called at coderef.pl line 6
      hmm it even works when passing parameters 8)

      DB<11> $codeRef= sub { print @_ } DB<12> sub doit (&) { $_[0]->("para") } DB<13> doit { &$codeRef } para

      But one should check about the costs of the extra call level ... maybe not too big.

      Cheers Rolf

        I might be off topic, but, wouldn't that probably lead to more obscuring of data which might be a good thing in OOP concept of closures-mediated security?

        Prototype checking has been disabled in both the following examples...

        my $coderef = sub {shift;}; my $val=$coderef->("Hello from down under"); sub doit{ print shift, $/; } &doit($val);
        or another more succinct way of achieving the same
        my $coderef = sub {shift;}; sub doit{ print shift, $/; } &doit($coderef->("Hello from down under"));
        Update: Added the following code demonstration to clarify what I mean:

        suppose I don't want the constructor to be directly modified from outside the package namespace of a class, so I return a reference to a closure from the constructor which can be indirectly accessed via an instance method of the class.

        #Closured.pm #!/usr/local/bin/perl -cw use strict; use warnings; package Closured; sub new{ our $self; my $closure = sub { shift; if(@_){ $self = shift; } return $self; }; bless $closure; return $closure; #returning a codeRef instead } sub name{ &{$_[0]}; } 1;
        #using the Closured class... use strict; use warnings; use Closured; my $object = Closured->new("Hisham"); #try to feed a constructor direc +tly. print $object,$/; #the constructor retruns a code ref. print $object->name("BioHisham"), "\n"; #Feed via an instance method
        #Output Closured=CODE(0x18449ac) BioHisham


        Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.

      Yes, but you're effectively making nested subroutine calls that way, which for small subs can mean a 25% to 30% performance hit


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.