Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > strange warning when open file

Reply
Thread Tools

strange warning when open file

 
 
George Mpouras
Guest
Posts: n/a
 
      08-15-2012
Do you have any idea how to fix the warning
Name "main::FH" used only once: possible typo at C:\work\Files\test.pl
at the following code ?



#!/usr/bin/perl
use strict;
use warnings;

my $output_dir = '/tmp';
my %File = (
'mc' => { '12' => '', '13' => '', },
'mp' => { '12' => '', '13' => '', },
);


foreach my $key1 (keys %File)
{
foreach my $key2 (keys %{$File{$key1}})
{
$File{$key1}{$key2} = { *FH => \"$key1,$key2" , 'FILE' =>
"$output_dir/$key1,$key2" };
open $File{$key1}{$key2}{'FH'}, '>', $File{$key1}{$key2}{'FILE'} or die
"Could not open file \"$File{$key1}{$key2}{'FILE'}\" because \"$^E\"\n";
}
}

# Write something
print {$File{nc}{12}{FH}} "test nc 12\n";
print {$File{alp}{14}{FH}} "test alp 14\n";

# Close the filehandlers
foreach my $key1 (keys %File) {
foreach my $key2 (keys %{$File{$key1}}) {
close $File{$key1}{$key2}{'FH'} or die "Could not close file
\"$File{$key1}{$key2}{'FILE'}\" because \"$^E\"\n" }}

 
Reply With Quote
 
 
 
 
George Mpouras
Guest
Posts: n/a
 
      08-15-2012
sorry for the tipo

print {$File{nc}{12}{FH}} "test nc 12\n";
print {$File{alp}{14}{FH}} "test alp 14\n";

should be

print {$File{mc}{12}{FH}} "test mc 12\n";
print {$File{mp}{13}{FH}} "test mp 13\n";

Of course the warning issue remains
 
Reply With Quote
 
 
 
 
Peter Makholm
Guest
Posts: n/a
 
      08-15-2012
"George Mpouras" <> writes:

> Do you have any idea how to fix the warning
> Name "main::FH" used only once: possible typo at C:\work\Files\test.pl
> at the following code ?


And it doesn't tell you a line number where it encounters the name
main::FH?

My perl does, it is on line 16.

> foreach my $key2 (keys %{$File{$key1}})
> {
> $File{$key1}{$key2} = { *FH => \"$key1,$key2" , 'FILE' => "$output_dir/$key1,$key2" };


i.e. this line.

You are using a variable called *FH here and nowhere else in your
script. Which is what perl tries to warn you about.

Variables using the * sigil is a class of variables called
typeglobs. Just like variables starting with the $ sigil ara scalars and
variables starting with the @ sigil is arrays.

Typeglobs are an internal type used by perl to hold symbol table
entries. Previously it was used for references and filehandles, but this
usage is deprecated. You can read more about typeglobs in the perldata
manual page.


What you probably meant was the string 'FH'. You can do this by either
just removing the * and use the stringification feature of the =>
operator or explicitly use a string like you do for the FILE field.

//Makholm
 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a
 
      08-15-2012
Peter Makholm <> writes:

[...]

> Variables using the * sigil is a class of variables called
> typeglobs. Just like variables starting with the $ sigil ara scalars and
> variables starting with the @ sigil is arrays.
>
> Typeglobs are an internal type used by perl to hold symbol table
> entries. Previously it was used for references and filehandles, but this
> usage is deprecated.


The short way to describe what 'a typeglob' actually is would be 'what
a symbol is in Lisp': An object which aggregates a number of 'slots'
used by the language for different purposes and which is usually
stored in a symbol table where it can be found by doing an 'ordinary'
name lookup which thus provides a way to employ the functionality
provided by the 'slots' by name. For a perl typeglob, the
commonly-used slots would be (assuming the name pointing to the typeglob was
richard) $richard, the slot used for scalars, %richard, the hash slot,
@richard, the array slot and lastly, the &richard slot for
subroutines. The *-notation can be used to refer to the typeglob
itself, eg, in the case of a named I/O handle (another typeglob slot),
the syntax \*richard could be used to pass a reference to that
(actually, to the typeglob itself) to a subroutine (*richard{IO} could
be used to create a reference to the 'thing' in the I/O handle slot).

Another use of *richard would be to assign a reference to something to
one of the slots, eg

*richard = sub { return 'richard'; }

creates an anonymous subroutine returning 'richard' and assigns a reference
to that to the subroutine slot of the glob associated with the name
richard. Effectively, this binds a name to this anonymous subroutine
(or vice versa). This is also the way how importing subroutines from
other modules works.

The reference to references refers to a deficiency of some ancient
programming language someone reportedly used somewhere about twenty
years ago. It ought to be forgotten nowadays. Likewise, in ancient
versions of Perl5, the only way to create an I/O handle was to refer
to a typeglob via the symbol table of the current package, eg

open(IN, '</etc/passwd')

will open the file /etc/passwd for reading and deposit the
corresponding I/O handle in the I/O handle slot of the typeglob
associated with the name IN. Nowadays, it is usually more convenient
to use an 'undefined' scalar variable for this purpose: This cause an
anonymous typeglob to be created and assigned to this variable
(actually, a reference to it is assigned). This has the nice
additional benefit that the filehandle will be closed automatically
when the scalar variable goes out of scope (be warned that this is
another highly blasphemous heresy because 'mighty sheep' garbage
collectors don't provide this functionality ...)
 
Reply With Quote
 
George Mpouras
Guest
Posts: n/a
 
      08-15-2012
The reference to references refers to a deficiency of some ancient
programming language someone reportedly used somewhere about twenty
years ago. It ought to be forgotten nowadays. Likewise, in ancient
versions of Perl5, the only way to create an I/O handle was to refer
to a typeglob via the symbol table of the current package, eg

open(IN, '</etc/passwd')



As you can see Rainer the code is dynamic. In reality the hash is also
dynamic, so I will end up with hundrends of open fileshat they will get
written also dynamic using the hash keys as filehanl pointers
So using a simple keyword like IN is not good enough.
I have to use the full path of hash keys as a unique FH identifier, othelse
all writings will be wrong.
This is why i used the * ...

 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      08-15-2012
George Mpouras wrote:
) As you can see Rainer the code is dynamic. In reality the hash is also
) dynamic, so I will end up with hundrends of open fileshat they will get
) written also dynamic using the hash keys as filehanl pointers
) So using a simple keyword like IN is not good enough.
) I have to use the full path of hash keys as a unique FH identifier, othelse
) all writings will be wrong.
) This is why i used the * ...

That's not how filehandle/fileglob references work.

Try this:

use strict;
use warnings;

my %x;
$x{one}{FILE} = "testfile-one.txt";
$x{two}{FILE} = "testfile-two.txt";
for my $xx (keys %x) {
open $x{$xx}{FH}, '>', $x{$xx}{FILE} or die "Failed to open: $_\n";
}
for my $xx (keys %x) {
print { $x{$xx}{$FH} } "Text for $xx\n" or die "Failed to print: $_\n";
}
for my $xx (keys %x) {
close $x{$xx}{FH} or die "Failed to close: $_\n";
}

And also try to figure out why it works.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
George Mpouras
Guest
Posts: n/a
 
      08-15-2012
Actually thats what I did. It works ( I wonder why ... )


# Open Files
foreach my $key1 (keys %File)
{
foreach my $key2 (keys %{$File{$key1}})
{
$File{$key1}{$key2} = { FH => undef , 'FILE' =>
"$output_dir/$key1,$key2" };
open $File{$key1}{$key2}{'FH'}, '>', $File{$key1}{$key2}{'FILE'} or die
"Could not open file \"$File{$key1}{$key2}{'FILE'}\" because \"$^E\"\n";
}
}

 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a
 
      08-15-2012
"George Mpouras" <> writes:
> Actually thats what I did. It works ( I wonder why ... )
>
>
> # Open Files
> foreach my $key1 (keys %File)
> {
> foreach my $key2 (keys %{$File{$key1}})
> {
> $File{$key1}{$key2} = { FH => undef ,


The assignment is not needed: The first time the other code uses
$File{$key1}{$key2}{FH} in a rvalue context which needs a reference
to a 'value' of some type, a suitable value will be created and a
reference to it assigned to the hitherto 'undefined' location
(so-called 'auto-vivification'). One of these contexts is the first
argument to an open call which is either supposed to be the name of a
typeglob or a reference to a type glob, cf the following example:

--------------
open($passwd, '<', '/etc/passwd');
print($passwd, "\n");
--------------

which (on a system where a file named /etc/passwd exists prints
the reference to the anonymous glob which was assigned to $passwd when
autovivification took place.

As Peter Makholm already wrote earlier: The error in your original
code was that you wrote

*FH => undef

in a hash definition. The =>-operator automaically quotes its left
argument if "it begins with a letter or underscore and is composed
only of letters, digits and underscores" (=> perlop(1)). This is not
the case here, hence *FH is evaluated as an expression. The value of
this expression is the typeglob currently associated with the name FH
in the symbol table of the current package, which causes the warning
to be printed. It will probably also not do what you wanted wrt
creating a hash entry because *FH stringfies to the fully-qualified
name of the referenced typeglob, cf

-----------
my $h = { *FH => 'FH' };

print $h->{*FH}, "\n";

package haha;

print $h->{*FH}, "\n";

print("The solution: ", keys(%$h), "\n");
-----------

[in German, the letter 'h' is pronounced 'ha']
 
Reply With Quote
 
George Mpouras
Guest
Posts: n/a
 
      08-15-2012
Thanks for the *info !
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: how to open a file in some application using Tkinter i am usingTKINTER to create GUI application i want to know how to open a worddocument in open office or any other applicatio Fredrik Lundh Python 1 01-09-2008 10:40 AM
WARNING! Prosoftstore.com is a SCAM! WARNING! pentologer@gmail.com ASP .Net Web Services 0 07-08-2007 10:03 AM
warning C4267 and warning C4996 B. Williams C++ 17 10-27-2006 09:41 PM
Warning: WARNING Charles Computer Support 7 08-16-2005 09:07 PM
Re: A code fix for MSVC warning C4267 (64-bit compatibility warning,e.g. Boost Spirit) Pete Becker C++ 0 02-10-2005 01:13 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57