associate + attach?

Discussion in 'Perl Misc' started by ivowel@gmail.com, Dec 9, 2006.

  1. Guest

    Dear perl experts: Is there a module to attach a variable to another
    variable, and retrieve it later?

    my $fh;
    open($fh, "filename");
    attach($fh, "filename");

    (PS: why is the open syntax not '$fh=open("filename")' ?)

    far, far, away, in one of many distant subroutines:

    my $fname= attached($fh);
    close($fh);
    system("mv $fname .$fname");

    I do understand that I can pass $fname around with $fh, or even put the
    two into an array and pass around the array.

    It's almost like "bless" semantics, where I want to attach something
    else to a variable, but in my case, it is not necessarily a class name.

    regards,

    /ivo
     
    , Dec 9, 2006
    #1
    1. Advertising

  2. wrote:
    > Dear perl experts: Is there a module to attach a variable to another
    > variable, and retrieve it later?
    >
    > my $fh;
    > open($fh, "filename");
    > attach($fh, "filename");
    >
    > (PS: why is the open syntax not '$fh=open("filename")' ?)


    Perhaps you are thinking of using typeglobs:

    our $FILE = "filename";

    open FILE or die $!;

    # *FILE contains both the file name and the filehandle.
    # this only works for reading files and using package variables




    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, Dec 9, 2006
    #2
    1. Advertising

  3. Dr.Ruud Guest

    schreef:

    > (PS: why is the open syntax not '$fh=open("filename")' ?)



    With the current syntax, you can do

    my $filename = 'abc.txt' ;
    open my $fh, '<', $filename
    or die "Couldn't open '$filename' for reading: $!" ;

    Feel free to create a sub myopen(), but read `perldoc -f open` first, to
    find out why hardly anybody does.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Dec 9, 2006
    #3
  4. On Dec 9, 2:34 am, wrote:
    > Dear perl experts: Is there a module to attach a variable to another
    > variable, and retrieve it later?
    >
    > my $fh;
    > open($fh, "filename");
    > attach($fh, "filename");
    >
    > (PS: why is the open syntax not '$fh=open("filename")' ?)


    History. In Perl4 you used bareword filehandles. These were interpreted
    as implicit symbolic refrerences to typelogbs.

    BTW it's usual to combine the variable declaration. You should also
    avoid the 2 argument open() which is another hangover from Perl4.

    open(my $fh,'<', "filename") or die $!;

    > far, far, away, in one of many distant subroutines:
    >
    > my $fname= attached($fh);
    > close($fh);
    > system("mv $fname .$fname");
    >
    > I do understand that I can pass $fname around with $fh, or even put the
    > two into an array and pass around the array.
    >
    > It's almost like "bless" semantics, where I want to attach something
    > else to a variable, but in my case, it is not necessarily a class name.


    In general there is something called "magic" but you can only get at
    magic if you are writing extensions in C.

    However Perl "file handles" are a special case. Although it's possible
    to use a reference to a Perl file handle thanks to the history
    mentioned above, what we usually use is in fact a reference to a Perl
    "typeglob" entity that contains (a reference to) the filehandle. This
    means that (most of the time) each Perl file handle carries with it an
    unused (reference to a) scalar, hash and array.

    You can get at the hidden scalar associated with a filehandle

    ${*$fh}

    This is often used to carry the filename. Of course there's only one
    scalar so if any other code in your program is using it for something
    else you are stuffed.

    To avoid conflicts there's a convention that module Foo::Bar can use
    the 'Foo::Bar' element of the hidden hash %{*$fh} i.e.
    ${*$fh}{'Foo::Bar'} to attach any information it wants to the
    filehandle. Of course this usually is used as another hashref so in
    Foo::Bar you'd set a private 'wibble' attribute thus:

    ${*$fh}{+__PACKAGE__}{wibble} = $wibble;
     
    Brian McCauley, Dec 9, 2006
    #4
  5. On 8 Dec 2006 18:34:24 -0800, wrote:

    >(PS: why is the open syntax not '$fh=open("filename")' ?)


    For historical reasons. But in Perl 6 it's actually like that.


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Dec 9, 2006
    #5
  6. Guest

    thanks again, everybody. learned something new. (file handling and
    typeglobs seem rather odd from my perspective, but I am beginning to
    learn some of the power that is hidden away in its messy underbelly.)

    to the extent that perl is a machine shop that does everything cheaply,
    I hope perl6 will just always keep the filename with the file
    reference, too (and perhaps leave ${*fh} for other uses). This seems
    like a rather useful feature in many situations...

    will this ${*fh} functionality survive the increment to perl6?

    regards,

    /ivo



    Brian McCauley wrote:
    > On Dec 9, 2:34 am, wrote:
    > > Dear perl experts: Is there a module to attach a variable to another
    > > variable, and retrieve it later?
    > >
    > > my $fh;
    > > open($fh, "filename");
    > > attach($fh, "filename");
    > >
    > > (PS: why is the open syntax not '$fh=open("filename")' ?)

    >
    > History. In Perl4 you used bareword filehandles. These were interpreted
    > as implicit symbolic refrerences to typelogbs.
    >
    > BTW it's usual to combine the variable declaration. You should also
    > avoid the 2 argument open() which is another hangover from Perl4.
    >
    > open(my $fh,'<', "filename") or die $!;
    >
    > > far, far, away, in one of many distant subroutines:
    > >
    > > my $fname= attached($fh);
    > > close($fh);
    > > system("mv $fname .$fname");
    > >
    > > I do understand that I can pass $fname around with $fh, or even put the
    > > two into an array and pass around the array.
    > >
    > > It's almost like "bless" semantics, where I want to attach something
    > > else to a variable, but in my case, it is not necessarily a class name.

    >
    > In general there is something called "magic" but you can only get at
    > magic if you are writing extensions in C.
    >
    > However Perl "file handles" are a special case. Although it's possible
    > to use a reference to a Perl file handle thanks to the history
    > mentioned above, what we usually use is in fact a reference to a Perl
    > "typeglob" entity that contains (a reference to) the filehandle. This
    > means that (most of the time) each Perl file handle carries with it an
    > unused (reference to a) scalar, hash and array.
    >
    > You can get at the hidden scalar associated with a filehandle
    >
    > ${*$fh}
    >
    > This is often used to carry the filename. Of course there's only one
    > scalar so if any other code in your program is using it for something
    > else you are stuffed.
    >
    > To avoid conflicts there's a convention that module Foo::Bar can use
    > the 'Foo::Bar' element of the hidden hash %{*$fh} i.e.
    > ${*$fh}{'Foo::Bar'} to attach any information it wants to the
    > filehandle. Of course this usually is used as another hashref so in
    > Foo::Bar you'd set a private 'wibble' attribute thus:
    >
    > ${*$fh}{+__PACKAGE__}{wibble} = $wibble;
     
    , Dec 10, 2006
    #6
  7. -berlin.de Guest

    <> wrote in comp.lang.perl.misc:
    >
    > Dear perl experts: Is there a module to attach a variable to another
    > variable, and retrieve it later?
    >
    > my $fh;
    > open($fh, "filename");
    > attach($fh, "filename");
    >
    > (PS: why is the open syntax not '$fh=open("filename")' ?)
    >
    > far, far, away, in one of many distant subroutines:
    >
    > my $fname= attached($fh);
    > close($fh);
    > system("mv $fname .$fname");
    >
    > I do understand that I can pass $fname around with $fh, or even put the
    > two into an array and pass around the array.
    >
    > It's almost like "bless" semantics, where I want to attach something
    > else to a variable, but in my case, it is not necessarily a class name.


    In addition to the suggestions that have been made, here is an OO
    approach: Based on the class IO::File add a feature that remembers
    the file name used to open the handle. This approach uses a simple
    inside-out class "FileName" to achieve this. The classes IO::File
    and FileName can be merged together via simple inheritance.

    Contrast this to the approach that uses the glob-structure of a file
    handle to store extra information. You must make your way to the
    hash slot of the glob, and you must follow fragile conventions to
    avoid clashes.

    The code below uses the feature Hash::Util::FieldHash to implement the
    inside-out class. This feature isn't available with the current
    perl, but bleadperl supports it.

    Anno


    #!/usr/local/bin/bleadperl
    use strict; use warnings; $| = 1;

    # MyFileHandle is an enhanced version of IO::Handle that remembers the
    # file name

    my $fh = MyFileHandle->new;
    $fh->open( '/tmp/x', '<') or die "Can't open /tmp/x: $!";
    print while <$fh>;
    print "+++ read from ", $fh->filename, "\n";
    exit;


    # A simple class with a single field "filename"
    BEGIN {
    use Hash::Util::FieldHash ();

    package FileName;

    Hash::Util::FieldHash::fieldhash my %filename;

    sub init {
    my $fn = shift;
    $filename{ $fn} = shift();
    $fn;
    }
    sub filename { $filename{ shift()} }
    }

    # Enhanced version of IO::File which remembers the file name
    BEGIN {
    use IO::File;
    package MyFileHandle;
    our @ISA = qw( IO::File FileName);

    # override open (simplified version)
    sub open {
    my ( $fh, $file, $mode) = @_;
    $fh->IO::File::eek:pen( $file, $mode);
    $fh->FileName::init( $file);
    }
    }
     
    -berlin.de, Dec 10, 2006
    #7
  8. On 9 Dec 2006 20:17:20 -0800, wrote:

    >to the extent that perl is a machine shop that does everything cheaply,
    >I hope perl6 will just always keep the filename with the file
    >reference, too (and perhaps leave ${*fh} for other uses). This seems
    >like a rather useful feature in many situations...


    In Perl 6 everything is an object, although you're not forced to think
    of it in those terms, so I suppose that the filename will be
    accessible as a method of the filehandle.

    >will this ${*fh} functionality survive the increment to perl6?


    AFAIK most definitely not: typeglobs are to be abandoned altogether.


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, Dec 10, 2006
    #8
    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. Angel
    Replies:
    2
    Views:
    592
    Kikoz
    Dec 26, 2003
  2. Dailan
    Replies:
    0
    Views:
    467
    Dailan
    Jun 16, 2004
  3. =?Utf-8?B?SmVUbUFu?=

    How do I associate one control with others>

    =?Utf-8?B?SmVUbUFu?=, Sep 24, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    743
    John Saunders
    Sep 24, 2004
  4. Replies:
    0
    Views:
    658
  5. Warren Tang
    Replies:
    1
    Views:
    548
    Warren Tang
    Sep 17, 2008
Loading...

Share This Page