Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: Local for lexicals

by LanX (Saint)
on Aug 10, 2009 at 22:39 UTC ( [id://787425]=note: print w/replies, xml ) Need Help??


in reply to Local for lexicals

I'm still not sure what your goal is, do you maybe want a nice syntax to achieve lambdas with named variables like in Ruby?

So in analogy to ruby

 lamb  = lambda  { |x, y, z| z = x + y}

you want to write

 $lamb = lambda ($x,$y,$z) => { $z = $x + $y }

such that  $lamb->(1,2,$a) sets $a to 3 ???

Cheers Rolf

Replies are listed 'Best First'.
Re^2: Local for lexicals
by JadeNB (Chaplain) on Aug 10, 2009 at 23:03 UTC
    Yes, exactly, although I'd also like
    $lamb = lambda ( $x, $y ) => sub { $x + $y }
    to be such that $lamb->(1, 2) returns 3.
      I think the most productive approach would be to post test code, assuring your intentions are understood, such that other stop posting speculative code...

      Anyway I doubt that your desired "my_local" (or better named "lex-local") is what you need, since $x,$y,$z will always also belong to the outer scope, making ugly side-effects probable!

      { #outer scope $lamb = lambda ( $x, $y, $z ) => sub { $x + $y } }

      the following is simple and very close but lacks the same aliasing like $_[0] does.

        $lamb = sub { my ($x,$y,$z) = @_; $x + $y }

      so using Data::Alias or Lexical::Alias might be what you need to install for lexicals. If you don't wanna install XS-Moduls try working with lex-refs

      DB<20> $lamb=sub { my($x,$y)=\(@_); $$x += $$y } DB<21> $a=10; $lamb->($a,5); print $a 15

      NOTE: Aliasing can always be achieved with * and pack-vars.

      Cheers Rolf

        { #outer scope $lamb = lambda ( $x, $y, $z ) => sub { $x + $y } }
        This is, in a sense, the crux of my problem—I don't want the values of $x, $y, and $z to leak from the inside out, or vice versa, even though they have meaning in the outer scope. In this case, there are many ways around it, which you and others have indicated, but I was just wondering if there was any reason that one had to work around it, or if there were a lex_local that could just be dropped in for lexicals as local can for globals.
        NOTE: Aliasing can always be achieved with * and pack-vars.
        I know about *, although it doesn't seem to do much for lexicals, but what do you mean by pack-vars?
        I think the most productive approach would be to post test code, assuring your intentions are understood, such that other stop posting speculative code...
        (I PM'd you about this, but, on further thought, it seems that there's no reason to keep it P. :-) ) I agree, since it seems pretty clear that I'm not doing a good job of indicating the problem that I'm trying to solve. However, I don't know how to improve. Do you have any suggestions? (This seems almost worthy of being a post in its own right ….)

      So what you really want are anon subs with named arguments. Have you looked at

      use signatures; my $lamb = sub ($x, $y) { $x + $y }; print( $lamb->(3,4), "\n" ); # 7

      Unfortunately, the following doesn't work

      use signatures; my $lamb = sub ($x) { $x = 4 }; my $y = 3; $lamb->($y); print("$y\n"); # 3 XXX want 4

      I also tried Sub::Signatures and Perl6::Subs. Both accept anonymous subs with named parameters. Neither pass the alias test.

      Maybe one of them can be fixed. Maybe it works with one of the other modules.

      Update: To spend the least amount of effort, your best bet is to fork signatures. It hooks itself into the parser to change

      sub (...) { ... }

      into

      sub { my (...) = @_; ... }

      By changing what gets injected (my (...) = @_;) to something like the following, you can achieve aliasing (which also fixes tied vars):

      Lexical::Alias::alias(my $x, $_[0]); Lexical::Alias::alias(my $y, $_[1]); Lexical::Alias::alias(my $z, $_[2]);

      It might be best to use copying semantics by default, while adding a mechanism to specify aliasing ("is rw"?). That would allow you to extend signatures instead of replacing it.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://787425]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-16 16:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found