Hi Marcos.

First let's remove some fog from your code. Your anonymous subroutine

  sub {$_ = 5;}

is returning the value '5' because that's the value of the assignment
operator '='. The assigment to $_ is serving no useful purpose as
$_ isn't used anywhere else. So we can reduce this to

  sub { return 5 }

Right, now lets fix some over-compression. your various versions
of

  sub a { }

are indirecting stuff off the stack and returning the result
of a procedure call, all in one line.

In addition your call to Dumper

  return Dumper(&{$_[0]})

has an explcit 'return' and explicit list delimiters '()'
whereas the call to &a

  a sub {$_ = 5;}

instead of

  a(sub {return $_ = 5})

has the opposite convention.

Now then, one by one:

Marcos Rebelo wrote:
>
> probably what I need is something about 'call back'
>
> Another example inside one script.
>
> this works:
>
> use Data::Dumper;
> sub a {
>     return Dumper(&{$_[0]});
> }
> print(a sub {$_ = 5;});

Is the same as

  sub a {
    my $sub = shift;
    return Dumper &$sub;
  }

  my $routine= sub {return 5};
  print(a $routine);

> This also works:
> use Data::Dumper;
> sub a(&) {
>     return Dumper(&{$_[0]});
> }
> print(a {$_ = 5;});

Is the same as

  sub a(&) {
    my $sub = shift;
    return Dumper &$sub;
  }

  print(a {return 5});

The difference here is that the prototype

  sub a(&)

turns the subroutine into a list operator, and insists
that the the list be either a code block (which it is)
a single subroutine reference.

If you were to call a(99) with the prototype set up then
at run-time the program would fail at the call because the
parameter was of the wrong type. Without it it would fail
at the

  Dumper &$sub

line because any parameter type was OK but it couldn't be
dereferenced here as a subroutine.

And, finally

> This no longuer works
> use Data::Dumper;
> sub a {
>     return Dumper(&{$_[0]});
> }
> print(a {$_ = 5;});

Is simply invalid syntax because

  a {$_ = 5;}

is using a bare code block in place of the parameter to &a. This
is different entirely from an anonymous subroutine. (You can pass
a code block as a parameter only if the subroutine is prototyped
as above. Otherwise you have to pass an anonymous subroutine.)

With the prototype you used in the second example this would be OK.
Like this:

  sub a(&) {
    my $sub = shift;
    return Dumper &$sub;
  }

  print(a {return 5});

> Is there some documentaction about this magic?

Your best place is

  perldoc perlsub

but don't get too engrossed in the fancy stuff. You will
almost never need subroutine prototypes.

HTH,

Rob



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to