using 2-arg open to open to a scalar

Discussion in 'Perl Misc' started by xhoster@gmail.com, Sep 2, 2008.

  1. Guest

    I'm looking for a value to put in $some_string so that the
    below code will have $y read from $scalar. I can't use the "<&4" syntax,
    since $x doesn't have a real fileno to be duped.


    open my $x, "<", \$scalar or die $!;
    open my $y, $some_string or die $!;

    The context of this is that I have an external (i.e. not my code) module
    which won't take a file-handle, it will only take a "filename" which gets
    passed to the 2-argument form of open. So I want to craft a magical
    "filename" that when given to 2-arg open, does what I want.

    Thanks,

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Sep 2, 2008
    #1
    1. Advertising

  2. wrote:
    > I'm looking for a value to put in $some_string so that the
    > below code will have $y read from $scalar. I can't use the "<&4" syntax,
    > since $x doesn't have a real fileno to be duped.
    >
    >
    > open my $x, "<", \$scalar or die $!;
    > open my $y, $some_string or die $!;
    >
    > The context of this is that I have an external (i.e. not my code) module
    > which won't take a file-handle, it will only take a "filename" which gets
    > passed to the 2-argument form of open. So I want to craft a magical
    > "filename" that when given to 2-arg open, does what I want.


    It will work with a package filehandle:

    $ perl -e'
    $scalar = <<TEXT;
    one two
    three four
    TEXT

    open IN, "<", \$scalar or die $!;
    open my $y, "<&=IN" or die $!;
    print while <IN>;
    print while <$y>;
    '
    one two
    three four
    one two
    three four



    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
     
    John W. Krahn, Sep 2, 2008
    #2
    1. Advertising

  3. wrote in news:20080902165755.862$:

    > I'm looking for a value to put in $some_string so that the
    > below code will have $y read from $scalar. I can't use the "<&4"
    > syntax, since $x doesn't have a real fileno to be duped.
    >
    >
    > open my $x, "<", \$scalar or die $!;
    > open my $y, $some_string or die $!;
    >
    > The context of this is that I have an external (i.e. not my code)
    > module which won't take a file-handle, it will only take a "filename"
    > which gets passed to the 2-argument form of open. So I want to craft
    > a magical "filename" that when given to 2-arg open, does what I want.


    C:\Temp> cat tt.pl
    #!/usr/bin/perl
    use strict;
    use warnings;

    use Alias;

    my $input_text = <<EOT;
    sdksdfk;lf';lk lk l;' k
    asfas;l's' k' k'adkd;fka'gka' ' ksf'sg
    ;sk;sdkg;skg;sk
    lsdf;ksdfk
    EOT

    open my $input, '<', \$input_text;
    alias INPUT => $input;

    myread( "<&=INPUT");

    sub myread {
    my ($fn) = @_;

    open my $h, $fn or die $!;
    print while <$h>;
    return;
    }

    __END__

    C:\Temp> tt
    sdksdfk;lf';lk lk l;' k
    asfas;l's' k' k'adkd;fka'gka' ' ksf'sg
    ;sk;sdkg;skg;sk
    lsdf;ksdfk


    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://www.rehabitation.com/clpmisc/
     
    A. Sinan Unur, Sep 3, 2008
    #3
  4. Guest

    "A. Sinan Unur" <> wrote:
    > wrote in news:20080902165755.862$:
    >
    > > I'm looking for a value to put in $some_string so that the
    > > below code will have $y read from $scalar. I can't use the "<&4"
    > > syntax, since $x doesn't have a real fileno to be duped.
    > >
    > >
    > > open my $x, "<", \$scalar or die $!;
    > > open my $y, $some_string or die $!;
    > >
    > > The context of this is that I have an external (i.e. not my code)
    > > module which won't take a file-handle, it will only take a "filename"
    > > which gets passed to the 2-argument form of open. So I want to craft
    > > a magical "filename" that when given to 2-arg open, does what I want.

    >
    > C:\Temp> cat tt.pl
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > use Alias;
    >
    > my $input_text = <<EOT;
    > sdksdfk;lf';lk lk l;' k
    > asfas;l's' k' k'adkd;fka'gka' ' ksf'sg
    > ;sk;sdkg;skg;sk
    > lsdf;ksdfk
    > EOT
    >
    > open my $input, '<', \$input_text;
    > alias INPUT => $input;
    >
    > myread( "<&=INPUT");


    Excellent, thanks. I just had to add the package name because in my
    case myread is in a different package.

    myread("<&=main::INPUT")

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Sep 4, 2008
    #4
  5. wrote in news:20080904072105.577$:

    > "A. Sinan Unur" <> wrote:
    >> wrote in news:20080902165755.862$:
    >>


    ....

    >> open my $input, '<', \$input_text;
    >> alias INPUT => $input;
    >>
    >> myread( "<&=INPUT");

    >
    > Excellent, thanks. I just had to add the package name because in my
    > case myread is in a different package.
    >
    > myread("<&=main::INPUT")


    Glad it worked. This is why I love this group: Prior to your post, I
    would never have thought about how to achieve what you want to achieve.
    This really helped me learn a lot about the open function some of whose
    features I had not paid much attention to before.

    Sinan

    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://www.rehabitation.com/clpmisc/
     
    A. Sinan Unur, Sep 4, 2008
    #5
  6. C.DeRykus Guest

    On Sep 2, 3:46 pm, "John W. Krahn" <> wrote:
    > wrote:
    > > I'm looking for a value to put in $some_string so that the
    > > below code will have $y read from $scalar. I can't use the "<&4" syntax,
    > > since $x doesn't have a real fileno to be duped.

    >
    > > open my $x, "<", \$scalar or die $!;
    > > open my $y, $some_string or die $!;

    >
    > > The context of this is that I have an external (i.e. not my code) module
    > > which won't take a file-handle, it will only take a "filename" which gets
    > > passed to the 2-argument form of open. So I want to craft a magical
    > > "filename" that when given to 2-arg open, does what I want.

    >
    > It will work with a package filehandle:
    >
    > $ perl -e'
    > $scalar = <<TEXT;
    > one two
    > three four
    > TEXT
    >
    > open IN, "<", \$scalar or die $!;
    > open my $y, "<&=IN" or die $!;
    > print while <IN>;
    > print while <$y>;
    > '
    > one two


    Or, if Alias isn't handy and you want a lexical filehandle instead:

    open my $fh, "+<", undef
    or die $!;
    print $fh $scalar;
    seek $fh, 0, 0 or die $!;

    open( my $y, "<&=@{[fileno $fh]}" )
    or die $!;

    --
    Charles DeRykus
     
    C.DeRykus, Sep 8, 2008
    #6
  7. Ben Morrow Guest

    Quoth "C.DeRykus" <>:
    >
    > open( my $y, "<&=@{[fileno $fh]}" )
    > or die $!;


    Blecch :).

    open my $y, "<&=", $fh or die ...;

    $fh can be replaced with "STDIN" or \*STDIN if you want to fdopen(3) an
    already-existing global filehandle.

    Ben

    --
    For far more marvellous is the truth than any artists of the past imagined!
    Why do the poets of the present not speak of it? What men are poets who can
    speak of Jupiter if he were like a man, but if he is an immense spinning
    sphere of methane and ammonia must be silent? [Feynmann]
     
    Ben Morrow, Sep 9, 2008
    #7
  8. Guest

    Ben Morrow <> wrote:
    > Quoth "C.DeRykus" <>:
    > >
    > > open( my $y, "<&=@{[fileno $fh]}" )
    > > or die $!;

    >
    > Blecch :).
    >
    > open my $y, "<&=", $fh or die ...;


    But the requirement was to use the 2-arg form of open, not the
    3-arg form.

    Well, that was the requirement. Despite the nice answers I've gotten here,
    I decided to I'd keep my own library with an updated version of the module
    which can take a file-handle in lieu of a string which is passed to 2-arg
    open, which obviates the whole mess. Now I just have the mess of multiple
    module versions in different places in @INC

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Sep 9, 2008
    #8
  9. Guest

    wrote:
    > Ben Morrow <> wrote:
    > > Quoth "C.DeRykus" <>:
    > > >
    > > > open( my $y, "<&=@{[fileno $fh]}" )
    > > > or die $!;

    > >
    > > Blecch :).
    > >
    > > open my $y, "<&=", $fh or die ...;

    >
    > But the requirement was to use the 2-arg form of open, not the
    > 3-arg form.
    >
    > Well, that was the requirement. Despite the nice answers I've gotten
    > here, I decided to I'd keep my own library with an updated version of the
    > module which can take a file-handle in lieu of a string which is passed
    > to 2-arg open, which obviates the whole mess. Now I just have the mess
    > of multiple module versions in different places in @INC


    By the way, what do people consider the "best practice" for detecting
    whether the thing passed in is a file-handle, rather than a filename?

    if (ref $_[0]) { #...

    Seems to be good enough to me. It works with lexicals and with foo(\*FH),
    but it fails with foo(*FH). I'm willing to live with that, but if there is
    something better which isn't overly complicated it would be better yet.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Sep 9, 2008
    #9
  10. Ben Morrow Guest

    Quoth :
    >
    > By the way, what do people consider the "best practice" for detecting
    > whether the thing passed in is a file-handle, rather than a filename?
    >
    > if (ref $_[0]) { #...
    >
    > Seems to be good enough to me. It works with lexicals and with foo(\*FH),
    > but it fails with foo(*FH). I'm willing to live with that, but if there is
    > something better which isn't overly complicated it would be better yet.


    use Scalar::Util qw/openhandle/;

    if (openhandle $_[0]) {

    is what I'd use. It doesn't catch \*FOO where FOO is not an open handle,
    nor cases like

    open my $x, "<", "foo";
    close $x;
    if (openhandle $x) {

    but that's probably what you wanted anyway.

    Ben

    --
    Many users now operate their own computers day in and day out on various
    applications without ever writing a program. Indeed, many of these users
    cannot write new programs for their machines...
    -- F.P. Brooks, 'No Silver Bullet', 1987 []
     
    Ben Morrow, Sep 9, 2008
    #10
  11. C.DeRykus Guest

    On Sep 9, 11:27 am, Ben Morrow <> wrote:
    > Quoth :
    >
    >
    >
    > > By the way, what do people consider the "best practice" for detecting
    > > whether the thing passed in is a file-handle, rather than a filename?

    >
    > > if (ref $_[0]) { #...

    >
    > > Seems to be good enough to me. It works with lexicals and with foo(\*FH),
    > > but it fails with foo(*FH). I'm willing to live with that, but if there is
    > > something better which isn't overly complicated it would be better yet.

    >
    > use Scalar::Util qw/openhandle/;
    >
    > if (openhandle $_[0]) {
    >
    > is what I'd use. It doesn't catch \*FOO where FOO is not an open handle,
    > nor cases like
    >
    > open my $x, "<", "foo";
    > close $x;
    > if (openhandle $x) {
    >
    > but that's probably what you wanted anyway.
    >


    Hm... Scalar::Util 1.18 seems to catch both cases:

    perl -lM"Scalar::Util 'openhandle'"
    open my $h,"<","/dev/null" or die;
    close $h or die;
    print openhandle $h ? "yes" : "no";
    ^D
    no


    perl -lM"Scalar::Util 'openhandle'"
    print openhandle \*FOO ? "yes"
    : "no";
    ^D
    no


    --
    Charles DeRykus
     
    C.DeRykus, Sep 10, 2008
    #11
  12. Guest

    "C.DeRykus" <> wrote:
    > On Sep 9, 11:27 am, Ben Morrow <> wrote:
    > > Quoth :
    > >
    > >
    > >
    > > > By the way, what do people consider the "best practice" for detecting
    > > > whether the thing passed in is a file-handle, rather than a filename?

    > >
    > > > if (ref $_[0]) { #...

    > >
    > > > Seems to be good enough to me. It works with lexicals and with
    > > > foo(\*FH), but it fails with foo(*FH). I'm willing to live with
    > > > that, but if there is something better which isn't overly complicated
    > > > it would be better yet.

    > >
    > > use Scalar::Util qw/openhandle/;
    > >
    > > if (openhandle $_[0]) {
    > >
    > > is what I'd use. It doesn't catch \*FOO where FOO is not an open
    > > handle, nor cases like
    > >
    > > open my $x, "<", "foo";
    > > close $x;
    > > if (openhandle $x) {
    > >
    > > but that's probably what you wanted anyway.
    > >

    >
    > Hm... Scalar::Util 1.18 seems to catch both cases:
    >
    > perl -lM"Scalar::Util 'openhandle'"
    > open my $h,"<","/dev/null" or die;
    > close $h or die;
    > print openhandle $h ? "yes" : "no";
    > ^D
    > no
    >
    > perl -lM"Scalar::Util 'openhandle'"
    > print openhandle \*FOO ? "yes"
    > : "no";
    > ^D
    > no


    Catch in the wrong sense. If the method is being given something
    that is either a handle or a filename, and it is supposed to detect
    the difference, then one would not want to try to open a stringified handle
    as if it were a filename when given something that is a handle but not
    an open one. (Especially if it will be for output)

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Sep 10, 2008
    #12
  13. C.DeRykus Guest

    On Sep 10, 3:20 am, wrote:
    > "C.DeRykus" <> wrote:
    > > On Sep 9, 11:27 am, Ben Morrow <> wrote:
    > > > Quoth :

    >
    > > > > By the way, what do people consider the "best practice" for detecting
    > > > > whether the thing passed in is a file-handle, rather than a filename?

    >
    > > > > if (ref $_[0]) { #...

    >
    > > > > Seems to be good enough to me. It works with lexicals and with
    > > > > foo(\*FH), but it fails with foo(*FH). I'm willing to live with
    > > > > that, but if there is something better which isn't overly complicated
    > > > > it would be better yet.

    >
    > > > use Scalar::Util qw/openhandle/;

    >
    > > > if (openhandle $_[0]) {

    >
    > > > is what I'd use. It doesn't catch \*FOO where FOO is not an open
    > > > handle, nor cases like

    >
    > > > open my $x, "<", "foo";
    > > > close $x;
    > > > if (openhandle $x) {

    >
    > > > but that's probably what you wanted anyway.

    >
    > > Hm... Scalar::Util 1.18 seems to catch both cases:

    >
    > > perl -lM"Scalar::Util 'openhandle'"
    > > open my $h,"<","/dev/null" or die;
    > > close $h or die;
    > > print openhandle $h ? "yes" : "no";
    > > ^D
    > > no

    >
    > > perl -lM"Scalar::Util 'openhandle'"
    > > print openhandle \*FOO ? "yes"
    > > : "no";
    > > ^D
    > > no

    >
    > Catch in the wrong sense. If the method is being given something
    > that is either a handle or a filename, and it is supposed to detect
    > the difference, then one would not want to try to open a stringified handle
    > as if it were a filename when given something that is a handle but not
    > an open one. (Especially if it will be for output)
    >


    Unless I'm missing the boat again
    though, wouldn't some combo of
    ref, openhandle, and arg inspection
    get even closer:


    > if (ref $_[0]) { #...
    > Seems to be good enough to me.
    > It works with lexicals and with
    > foo(\*FH),
    > but it fails with foo(*FH).


    Maybe something along these lines..

    if( not ref $_[0]
    and not defined openhandle $_[0]
    and substr($_[0],0,1) ne '*' )
    # filename...
    }


    --
    Charles DeRykus
     
    C.DeRykus, Sep 11, 2008
    #13
  14. Ben Morrow Guest

    Quoth "C.DeRykus" <>:
    >
    > Maybe something along these lines..
    >
    > if( not ref $_[0]
    > and not defined openhandle $_[0]
    > and substr($_[0],0,1) ne '*' )


    Better would be

    ref \$_[0] ne 'GLOB'

    or maybe even

    ref \$_[0] eq 'SCALAR'

    as otherwise you can't use files whose names begin with '*'...

    Ben

    --
    Every twenty-four hours about 34k children die from the effects of poverty.
    Meanwhile, the latest estimate is that 2800 people died on 9/11, so it's like
    that image, that ghastly, grey-billowing, double-barrelled fall, repeated
    twelve times every day. Full of children. [Iain Banks]
     
    Ben Morrow, Sep 11, 2008
    #14
    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. n00m
    Replies:
    5
    Views:
    413
  2. Clint Olsen
    Replies:
    6
    Views:
    405
    Jeff 'japhy' Pinyan
    Nov 13, 2003
  3. Mark

    Replace scalar in another scalar

    Mark, Jan 27, 2005, in forum: Perl Misc
    Replies:
    4
    Views:
    193
    Arndt Jonasson
    Jan 27, 2005
  4. Replies:
    7
    Views:
    204
  5. Replies:
    21
    Views:
    426
    Barry Schwarz
    Mar 5, 2014
Loading...

Share This Page