A problem with storing a filehandle as an instance variable

Discussion in 'Perl Misc' started by Sniff, Dec 21, 2007.

  1. Sniff

    Sniff Guest

    I have been working with Perl for a few months now and in my latest
    program I decided to give Perl OO a try. :)

    In an object I'm trying to use a Filehandle (or Glob) which is uses to
    communicate with a child. I have been trying to keep these handles in
    an instance variable but it doesn't seem to work. I have tried a few
    different ways but I think I'm having issues dereferencing the
    variables.

    Here are some of the ways I have tried to do this:

    In my class constructor I do this:

    my $fhw = *write{FILEHANDLE};
    $self->{"WRITE"} = $fhw;
    # ... repeated for READ, ERROR ...
    # Then I call open3 with those 3 handles
    open3( $self->{"WRITE"}, $self->{"READ"}, $self->{"ERROR"},
    "worker.pl" );

    Later in a method I tried :

    print $self->{"WRITE"} "$someMessage\n" ; # this creates a syntax
    error, why?

    I also tried this:
    In the class constructor:
    $self->{"WRITE"} = \*WRITE; #using a reference to a globtype
    #later on I call open3 as I did above
    Then in a method I tried :
    print {$self->{"WRITE"}} "$message\n" ; #No error but I don't
    think it worked

    My first version of all this code was written in non-OO style and it
    works fine, but I was using a bareword (i.e. *WRITE) for the file
    handles. Any help would be appreciated.
    Sniff, Dec 21, 2007
    #1
    1. Advertising

  2. Sniff wrote:
    >
    > I have been working with Perl for a few months now and in my latest
    > program I decided to give Perl OO a try. :)
    >
    > In an object I'm trying to use a Filehandle (or Glob) which is uses to
    > communicate with a child. I have been trying to keep these handles in
    > an instance variable but it doesn't seem to work. I have tried a few
    > different ways but I think I'm having issues dereferencing the
    > variables.
    >
    > Here are some of the ways I have tried to do this:
    >
    > In my class constructor I do this:
    >
    > my $fhw = *write{FILEHANDLE};


    *write{FILEHANDLE} is the 'FILEHANDLE' (or 'IO') slot in the symbol
    table of the 'write' package variable so are we to assume that you used
    open( write, ">filename" ) to create the filehandle?


    > $self->{"WRITE"} = $fhw;


    You need to assign a reference to the filehandle typeglob:

    $self->{ WRITE } = \*write;


    > # ... repeated for READ, ERROR ...
    > # Then I call open3 with those 3 handles
    > open3( $self->{"WRITE"}, $self->{"READ"}, $self->{"ERROR"},
    > "worker.pl" );
    >
    > Later in a method I tried :
    >
    > print $self->{"WRITE"} "$someMessage\n" ; # this creates a syntax
    > error, why?


    perldoc -f print
    [ SNIP ]
    Note that if you're storing FILEHANDLEs in an array, or
    if you're using any other expression more complex than a
    scalar variable to retrieve it, you will have to use a
    block returning the filehandle value instead:

    print { $files[$i] } "stuff\n";
    print { $OK ? STDOUT : STDERR } "stuff\n";

    So you have to write that as:

    print { $self->{ WRITE } } "$someMessage\n";


    > I also tried this:
    > In the class constructor:
    > $self->{"WRITE"} = \*WRITE; #using a reference to a globtype


    Here you use WRITE in upper case. So is the filehandle write or WRITE?


    > #later on I call open3 as I did above
    > Then in a method I tried :
    > print {$self->{"WRITE"}} "$message\n" ; #No error but I don't
    > think it worked
    >
    > My first version of all this code was written in non-OO style and it
    > works fine, but I was using a bareword (i.e. *WRITE) for the file
    > handles.


    *WRITE is a typeglob, WRITE is a bareword.


    It is probably better to just use lexical variables for filehandles:

    open my $fhw, '>', 'filename' or die "... $!";

    $self->{ WRITE } = $fhw;


    perldoc -f open
    perldoc perlopentut


    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Dec 21, 2007
    #2
    1. Advertising

  3. Sniff

    Ben Morrow Guest

    Quoth "John W. Krahn" <>:
    <snip sound advice>
    >
    > It is probably better to just use lexical variables for filehandles:


    Unfortunately this doesn't work with open3, which is what the OP was
    using.

    Ben
    Ben Morrow, Dec 21, 2007
    #3
  4. Ben Morrow <> writes:

    > Quoth "John W. Krahn" <>:
    > <snip sound advice>
    >>
    >> It is probably better to just use lexical variables for filehandles:

    >
    > Unfortunately this doesn't work with open3, which is what the OP was
    > using.


    Lexical variables does work with open3 and it even shown in the
    documentation, except that you have to do some magic to get the error
    filhandle to work:

    use Symbol;
    my ($in, $out, $err);
    # Generate filehandle for $err so it's not false:
    $err = gensym;

    my $pid = open3($in,$out,$err,'cmd');

    //Makholm
    Peter Makholm, Dec 21, 2007
    #4
  5. Sniff

    Sniff Guest

    Well, I'm learning more than I ever wanted to about Perl Filehandles
    and typeglob :). I hacked at it last night and final got it to work
    by doing this:

    in contructor:
    my $fhw = *wr{FILEHANDLE};
    $self->{"WRITE"} = $fhw;

    in my method:
    local(*WRITE);
    *WRITE = $self->{"WRITE"};
    print *WRITE "$flag\n" ;

    Now I'm going to take some time to absorb the info you gave me above
    and incorporate that knowledge into how I'm using the handles.

    Thanks to John, Ben and Makholm
    Sniff, Dec 21, 2007
    #5
  6. Sniff

    Sniff Guest

    On Dec 21, 11:21 am, Sniff <> wrote:
    > Well, I'm learning more than I ever wanted to about Perl Filehandles
    > and typeglob :).  I hacked at it last night and final got it to work
    > by doing this:
    >
    > in contructor:
    >    my $fhw = *wr{FILEHANDLE};
    >    $self->{"WRITE"} = $fhw;
    >
    > in my method:
    >    local(*WRITE);
    >    *WRITE  = $self->{"WRITE"};
    >    print *WRITE "$flag\n" ;


    TYPO: Should be
    print WRITE "$flag\n" ;

    >
    > Now I'm going to take some time to absorb the info you gave me above
    > and incorporate that knowledge into how I'm using the handles.
    >
    > Thanks to John, Ben and Makholm
    Sniff, Dec 21, 2007
    #6
  7. Sniff

    Uri Guttman Guest

    >>>>> "S" == Sniff <> writes:

    S> Well, I'm learning more than I ever wanted to about Perl Filehandles
    S> and typeglob :). I hacked at it last night and final got it to work
    S> by doing this:

    S> in contructor:
    S> my $fhw = *wr{FILEHANDLE};

    stop doing that! that is not doing what you think it does. it gets the
    handle slot of a glob, but NOT a handle. there is NO REASON for you to
    use that syntax to get a handle.

    you can use IO::Handle or Symbol::gensym to get new handles. or use open
    with a undefined lexical. but STOP using the above construct!

    S> in my method:
    S> local(*WRITE);
    S> *WRITE = $self->{"WRITE"};

    use a lexcial to hold handles. globs (even localized) are very old
    fashioned.

    my $wr = IO::Handle->new() ;

    or
    open( my $wr, '>', $file ) or die "can't create $file" ;

    S> print *WRITE "$flag\n" ;

    S> Now I'm going to take some time to absorb the info you gave me above
    S> and incorporate that knowledge into how I'm using the handles.

    better to forget what you know about globs and learn about lexicals and
    handles.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Dec 21, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gerry Sutton
    Replies:
    1
    Views:
    523
    Peter Otten
    Apr 16, 2005
  2. toton
    Replies:
    11
    Views:
    690
    toton
    Oct 13, 2006
  3. Jonathan Wood
    Replies:
    1
    Views:
    489
    Jonathan Wood
    Jun 2, 2008
  4. mathias

    filehandle to variable problem

    mathias, Jul 15, 2003, in forum: Perl Misc
    Replies:
    3
    Views:
    90
    mathias
    Jul 17, 2003
  5. Replies:
    2
    Views:
    75
Loading...

Share This Page