Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Seeking balance from the <> operator

by GrandFather (Saint)
on Jun 18, 2008 at 04:49 UTC ( [id://692614]=perlquestion: print w/replies, xml ) Need Help??

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

Code of the form:

while (< $self->{fhFrom} >) {

is reported as a syntax error by Perl because it sees <$self-> as the diamond operator and contents - which doesn't quite Do What I Mean.

I can fix the problem by using a temporary variable to hold the file handle, but is there some obvious (or otherwise) syntactic construct I'm missing that allows me to use a file handle stored in a hash reference directly inside the diamond operator?


Perl is environmentally friendly - it saves trees

Replies are listed 'Best First'.
Re: Seeking balance from the <> operator
by ysth (Canon) on Jun 18, 2008 at 07:41 UTC
Re: Seeking balance from the <> operator
by Anonymous Monk on Jun 18, 2008 at 06:11 UTC
    I can fix the problem by using a temporary variable to hold the file handle, but is there some obvious (or otherwise) syntactic construct I'm missing that allows me to use a file handle stored in a hash reference directly inside the diamond operator?
    No. See perlop
    If what's within the angle brackets is neither a filehandle nor a simple scalar variable containing a filehandle name, typeglob, or typeglob reference, it is interpreted as a filename pattern to be globbed, and either a list of filenames or the next filename in the list is returned, depending on context. This distinction is determined on syntactic grounds alone. That means <$x> is always a readline() from an indirect handle, but <$hash{key}> is always a glob(). That's because $x is a simple scalar variable, but $hash{key} is not--it's a hash element.
Re: Seeking balance from the <> operator
by kyle (Abbot) on Jun 18, 2008 at 05:41 UTC

    I think the best you can do is use IO::Handle and then call getline on it instead.

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use IO::Handle; open my $fh, '<', $0 or die "Can't read myself: $!\n"; my $self = { fhFrom => $fh }; my $fh2 = ${$self}{fhFrom}; my %line_from; chomp( $line_from{var} = <$fh2> ); chomp( $line_from{expr} = <${$self}{fhFrom}> ); chomp( $line_from{graff} = <$$self{fhFrom}> ); chomp( $line_from{getline} = $self->{fhFrom}->getline ); print Dumper \%line_from; __END__ $VAR1 = { 'var' => '#!/usr/bin/perl' 'graff' => 'GLOB(0x504290)', 'getline' => 'use strict;', 'expr' => 'GLOB(0x504290)', };

    I don't know the nuts and bolts of it, but once the "stuff" inside <stuff > gets "too complicated", it treats it like glob.

Re: Seeking balance from the <> operator
by graff (Chancellor) on Jun 18, 2008 at 05:33 UTC
    Have you tried it like this:
    while (< $$self{fhFrom} >) {
    UPDATE: Sorry, I should have tried that myself before posting it. It doesn't seem to work as hoped for:
    perl -e 'open(my $fh,".bashrc");$h={ f => $fh };while(<$$h{f}>){print} +'
    that just prints "GLOB(0x00blah)", which is not what I wanted.

    Assigning the hashref value to a temporary scalar variable seems to be the only way to make the diamond operator do what you expect it to do. I think I've seen an explanation for this somewhere...

    ANOTHER UPDATE: It seems that it is not the dereference ($$ref{key} or $ref->{key}) that causes the problem -- it's just the presence of anything other than a plain scalar variable:

    $ perl -MData::Dumper=Dumper -e 'open(my $fh,".bashrc") or die; my %h=(f => $fh);print Dumper(\%h); while(<$h{f}>){print}' $VAR1 = { 'f' => \*{'::$fh'} }; GLOB(0x800d80) $ perl -MData::Dumper=Dumper -e 'open(my $fh,".bashrc") or die; my @h=($fh);print Dumper(\@h); while(<$h[0]>){print}' $VAR1 = [ \*{'::$fh'} ]; GLOB(0x800d80)
    (i.e. both cases fail to actually read from the file handle; the while loop prints the GLOB thing instead)

      I went down exactly the same path resulting in printing globs and other odd stuff before posting. Sorry, I should have mentioned that and saved you some time. AnonyMonk has nailed it with Re: Seeking balance from the <> operator. Assignment to a scalar is what it has to be.


      Perl is environmentally friendly - it saves trees
Re: Seeking balance from the <> operator
by ferreira (Chaplain) on Jun 18, 2008 at 13:36 UTC

    The recourse to a temp variable or readline is really unavoidable as explained by this piece of perlop:

    If what's within the angle brackets is neither a filehandle nor a simple scalar variable containing a filehandle name, typeglob, or typeglob reference, it is interpreted as a filename pattern to be globbed, and either a list of filenames or the next filename in the list is returned, depending on context. This distinction is determined on syntactic grounds alone. That means <$x> is always a readline() from an indirect handle, but <$hash{key}> is always a glob(). That's because $x is a simple scalar variable, but $hash{key} is not--it's a hash element. Even <$x > (note the extra space) is treated as glob("$x "), not readline($x).

Log In?
Username:
Password:

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

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

    No recent polls found