Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Moose and File::Temp

by gsiglet (Acolyte)
on Nov 19, 2012 at 12:21 UTC ( #1004523=perlquestion: print w/replies, xml ) Need Help??
gsiglet has asked for the wisdom of the Perl Monks concerning the following question:

Am I doing something wrong (probably) or is this some sort of bug? The following code throws an error.
package '' use Moose; use File::Temp; has 'tempfile' => ( is => 'rw', isa => 'File::Temp' ); sub BUILD { my $self = shift; my $args = shift; $self->{tempfile} = File::Temp->new(UNLINK => 1, SUFFIX => '.tmp'); print $self->{tempfile} "I am here"; }
And the error
String found where operator expected at line 16, near "} "I am + here"" (Missing operator before "I am here"?)
If you write
$self->{tempfile} = File::Temp->new(UNLINK => 1, SUFFIX => '.tmp'); my $tmp = $self->{tempfile}; print $tmp "I am here";
then it is working. Anybody has any idea? Thanks a lot

Replies are listed 'Best First'.
Re: Moose and File::Temp
by ColonelPanic (Friar) on Nov 19, 2012 at 12:41 UTC
    When a filehandle reference is contained in something more complex than a simple scalar variable, it has to be surrounded by braces:
    print {$self->{tempfile}} "I am here";

    Otherwise, the interpreter doesn't realize that is a filehandle.

    Some, though not all, monks consider it a good practice to always use braces for filehandle references.

    When's the last time you used duct tape on a duct? --Larry Wall
Re: Moose and File::Temp
by 2teez (Vicar) on Nov 19, 2012 at 13:03 UTC

    hi gsiglet,

    Just as ColonelPanic, mentioned previously,

    The following from print, in Perl Documentation could shield more light:

    If you're storing handles in an array or hash, or in general whenever you're using any expression more complex than a bareword handle or a plain, unsubscripted scalar variable to retrieve it, you will have to use a block returning the filehandle value instead, in which case the LIST may not be omitted:
    print { $files[$i] } "stuff\n";

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: Moose and File::Temp
by tobyink (Abbot) on Nov 19, 2012 at 13:19 UTC

    The two answers above should address the problem you're having. Here are some style tips though...

    In these two lines, you are treating $self like it is a hashref...

    $self->{tempfile} = File::Temp->new(UNLINK => 1, SUFFIX => '.tmp'); print $self->{tempfile} "I am here";

    But self is not a hashref; it's an object. OK, so Moose implements objects as blessed hashrefs by default, but it is considered bad form to treat an object as a hashref - we're supposed to pretend that it's not a hashref, and only access the internals via the accessors that Moose gives us. So we should do this...

    $self->tempfile( File::Temp->new(UNLINK => 1, SUFFIX => '.tmp') ); print {$self->tempfile} "I am here";

    The reasons for doing so are not just theoretical. Accessing the object as a hashref bypasses all your type constraints, triggers, etc.

    Secondly, you are initialising an attribute within the BUILD method. While you can do that, Moose does provide attribute defaults and builders for this sort of thing:

    package test; # not '' use Moose; use File::Temp; has tempfile => ( is => 'rw', isa => 'File::Temp', lazy => 1, default => sub { File::Temp->new(UNLINK => 1, SUFFIX => '.tmp') }, ); sub BUILD { my $self = shift; print { $self->tempfile } "I am here"; }
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Moose and File::Temp
by gsiglet (Acolyte) on Nov 19, 2012 at 13:53 UTC
    Are your remarks relevant to the following issue as well?
    package test; use Moose; use FileHandle; has 'fh' => ( is => 'rw', isa => 'FileHandle', lazy => 1, default => sub { FileHandle->new }, ); sub BUILD { my $self = shift; open $self->{fh} , "<", "temp.txt"; while (<$self->{fh}>) { print $_; } }
    This also throws an error:
    Syntax error at line 17, near "<$self->{fh"

      You may have some difficulty with isa => 'FileHandle' because while FileHandle is a core Perl module, Moose uses the type constraint string "FileHandle" to refer to unblessed Perl file handles - i.e. not objects created by the FileHandle package.

      open my $fh , "<", "temp.txt"; $self->fh($fh); while (<$fh>) { print $_; }
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
        So it is impossible to use  while(<$self->{IamAfileHandleAttribute}>) { ... } > to read a file, outside my constructor. I guess I will have to do:
        my $temp_fh = $self->{IamAfileHandleAttribute}; while (<$temp_fh>) { ... }
Re: Moose and File::Temp
by gsiglet (Acolyte) on Nov 19, 2012 at 13:14 UTC
    Thank you for your replies. Still got a lot to learn :)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1004523]
Approved by Athanasius
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2018-07-17 23:28 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (381 votes). Check out past polls.