associate + attach?

I

ivowel

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
 
J

John W. Krahn

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
 
D

Dr.Ruud

(e-mail address removed) 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.
 
B

Brian McCauley

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;
 
I

ivowel

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
 
A

anno4000

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);
}
}
 
M

Michele Dondi

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top