Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of rafael (2125)

Wednesday February 04, 2004
05:04 AM

lexical $_

[ #17203 ]
The new lexical $_ feature is in bleadperl since last night. More to come, as usual, in the P5P summary. (Which I didn't published this week, not out of laziness or something, but because very few things actually happened on P5P, besides the noise generated by evil mail worms. The next summary will cover two weeks.)
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • sub mylc { lc } (Score:3, Interesting)

    by Juerd (1796) on 2004.02.04 7:10 (#28030) Homepage
    Is there any way to get the caller's $_, like with Perl 6 $CALLER::_?
    • Do you mean the caller's lexical $_, if it has one ?

      Well, lexical $_ is no different from other lexical variables. So I imagine PadWalker [cpan.org] will work with it.

      If you write:
      my $_; sub mylc { lc } then the lc will act on the lexical $_. (I.e. you'll have a closure.)

      • So the gap between built-ins and user defined functions gets even larger than it already is. With no clean way to access the caller's lexical $_ (PadWalker's nice, but not something I'd like to use on a regular basis) and built-ins that do work on that lexical $_, creating functions that work like built-ins gets hard.

        Closures aren't good enough, because you can't import them and many people do like to have utility functions in modules.

        The lexical $_ sounded like a good idea, but having a special variable
        • A few points:

          "my $_" is an addition, not a replacement. It's 100% backwards-compatible.

          You can import closures, as long as they're not anonymous. But by doing so you "import" their lexicals as well.

          What you want is (as I understand it) to define a function that defaults to $_, as in :

          sub f(;$){my $arg = @_ ? $_[0] : $CALLER::_;...}

          This is unrelated to the ability of my'ing $_, which is introduced to solve side-effect and scoping problems, as well as problems with "local $_" versus magic. May I point

          • If I read p5p correctly, "lc" will still operate on the current $_, even if it is lexical.

            But my contrived "mylc" would no longer work as with a global $_.

            sub mylc { lc }
             
            our $_ = "FOO";
            print lc;    # foo
            print mylc;  # foo
             
            my $_ = "FOO";
            print lc;    # foo
            print mylc;  # FOO

            The point of having a default variable is not having to type it! But you now have to pass it to "mylc" explicitly if it is lexical.

            I understand that you want a lexical variable because you do

            • But my contrived "mylc" would no longer work as with a global $_. No, it will indeed. Just try it :) Look:

              $ bleadperl -le 'sub f{print}$_=1;my$_=2;f'
              1

              Here f()'s body is not in a scope where a lexical $_ is defined. Hence it will not use it. Really the difference between $_ and my $_ is the same than the difference between $x and my $x. You don't need to learn new things. And this new feature doesn't make you loose anything.

              • Thank you for explaining how lexicals work. I am aware of scoping in Perl.

                All I'm asking for is a cheat to get the $_ in the caller's lexical scope.

                I am assuming that my $_ = 3; print; will actually output 3. Builtins often use $_ as the default value if no argument is given. My own utility functions also do that. I'd like to use lexical $_, but I'd also like to keep using utility functions the way I'm using builtins. Without scary stuff like PadWalker.

                I'm not familiar with perl's guts, but is it hard to
                • Maybe you're too excited about the change that you don't see my point :) Thanks for your patience!

                  CALLER:: is feasible, I think it won't be difficult. So, assuming it gets implemented, the idiom to get the current default variable would be :

                  my $arg = exists $CALLER::{_} ? $CALLER::_ : $_;

                  This has the advantage of being valid in perl 5.8 and below. Assuming none of your modules is called CALLER.pm !

                  You're most welcome to post your thoughts to P5P. You definitively have a point about CALLER an d I'd like