Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Declare my variable in sysread - Mojo::File::slurp

by srchulo (Sexton)
on Dec 21, 2018 at 16:46 UTC ( [id://1227574]=perlquestion: print w/replies, xml ) Need Help??

srchulo has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I have a question about some code I saw in Mojo::File. In the slurp method, you see this:

sub slurp { my $self = shift; CORE::open my $file, '<', $$self or croak qq{Can't open file "$$self +": $!}; my $ret = my $content = ''; <b>while ($ret = $file->sysread(my $buffer, 131072, 0)) { $content . += $buffer }</b> croak qq{Can't read from file "$$self": $!} unless defined $ret; return $content; }

Inside the while, you see my $buffer used as the first argument to sysread, and then used in the body of the while loop. I've never seen this before, where you declare a variable as an argument and then access it later. Can anyone explain how this works? Is the body of the while loop able to access $buffer because the while loop's scope includes anything in the parentheses or the body of the loop?

Replies are listed 'Best First'.
Re: Declare my variable in sysread - Mojo::File::slurp
by choroba (Cardinal) on Dec 21, 2018 at 16:59 UTC
    It's the same trick as in
    while (my $line = <$fh>) {
    which is a shorthand for
    while (defined( my $line = readline($fh) )) {
    where, again, my $line appears as an argument operand of = which in turn is an argument operand of defined. my has two effects, one compile time and one run time. In compile time, you declare a lexical variable, and in runtime, you use it as an lvalue (i.e. assign a value to it). Variables declared in block conditions (if, while, unless, until) are accessible until the last conditional operator block.
    if (my $x = func()) { print "$x accesible here"; } elsif ($x eq 0) { # even here, print "and also here: $x"; }

    Updated.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      my $line appears as an argument of defined.

      No, it doesn't. It's an operand of =, not defined.

        But the = is, in turn, an argument operand to defined.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      my $line appears as an argument of = which in turn is an argument of defined.

      You're still claiming my $line is an argument of defined, and it's not. Operators have operands (not arguments), and the variable $line is defined's operand.

Re: Declare my variable in sysread - Mojo::File::slurp
by jwkrahn (Abbot) on Dec 21, 2018 at 19:35 UTC

    This is one of the idiosyncrasies of scoping that is rarely talked about.

    while ( my $var = ... ) { # $var visible here } continue { # $var also visible here } if ( my $var = ... ) { # $var visible here } elsif ( ) { # $var also visible here } else { # $var also visible here }
Re: Declare my variable in sysread - Mojo::File::slurp
by ikegami (Patriarch) on Dec 22, 2018 at 00:39 UTC

    You say you've never seen this before, but you've done in a million times. Just look at the previous line of your code.

    open my $file, ...

    my $var not only declares the variable at compile-time, it also returns the variable (as an lvalue) as if you had simply written $var.

Re: Declare my variable in sysread - Mojo::File::slurp
by Anonymous Monk on Dec 21, 2018 at 23:26 UTC
    Hi

    How do you suppose CORE::open my $file works in sub slurp?

    What if it was written as  while( CORE::open my $file ... ){ ... } ?

    The two arent much different

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2024-04-20 05:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found