Perl file handling

Perl file handling

am 22.09.2011 10:54:59 von Maggs

am trying to open a file but the problem is on the third line
(open...)

sub open_file {
local $/ = undef;
($filevar, $filemode, $filename) = @_;
open ($filevar, $filemode . $filename) || die ("Can't open
$filename");
}
everytime i run it i get the error: Can't use string ("FILE1") as a
symbol ref while "strict refs" in use.

Any help please on how to sort this out.


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Perl file handling

am 22.09.2011 16:07:12 von Brandon McCaig

On Thu, Sep 22, 2011 at 4:54 AM, Maggs wrote:
> ($filevar, $filemode, $filename) = @_;
> open ($filevar, $filemode . $filename) || die ("Can't open
> $filename");
> }
> everytime i run it i get the error: Can't use string ("FILE1") as a
> symbol ref while "strict refs" in use.

$filevar probably contains a value other than undef (apparently
'FILE1'), so open is trying to use its value as a symbolic
reference (something that the strict pragma disallows).

A symbolic reference basically means that the string contains the
name of the variable to use. It's a very obscure and bad
practice, which is why strict disallows it.

Use a new variable or pass an already undef variable into
open_file for the $filevar variable. See perldoc open.

You should also be using the three-argument open instead of
concatenating $filemode and $filename together.

You should actually be able to just pass the arguments to
open_file on to open directly:

sub open_file
{
open @_ or die "Can't open '$filename': $!";
}

# Call by using my to create $fh with undef, just like with raw
# open:
open_file my $fh, '<', 'foobar';

# Or undef the variable first:
undef $fh;

open_file $fh, '<', 'foobar';

(All of that is untested)

May I ask what the purpose of open_file is anyway? It seems to be
a simple wrapper over open that dies when open fails. Is that all
it does? Perhaps you should see if autodie does what you want?
See perldoc autodie.


--
Brandon McCaig
V zrna gur orfg jvgu jung V fnl. Vg qbrfa'g nyjnlf fbhaq gung jnl.
Castopulence Software

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Perl file handling

am 22.09.2011 17:09:21 von jwkrahn

Brandon McCaig wrote:
> On Thu, Sep 22, 2011 at 4:54 AM, Maggs wrote:
>> ($filevar, $filemode, $filename) = @_;
>> open ($filevar, $filemode . $filename) || die ("Can't open
>> $filename");
>> }
>> everytime i run it i get the error: Can't use string ("FILE1") as a
>> symbol ref while "strict refs" in use.
>
> $filevar probably contains a value other than undef (apparently
> 'FILE1'), so open is trying to use its value as a symbolic
> reference (something that the strict pragma disallows).
>
> A symbolic reference basically means that the string contains the
> name of the variable to use. It's a very obscure and bad
> practice, which is why strict disallows it.
>
> Use a new variable or pass an already undef variable into
> open_file for the $filevar variable. See perldoc open.
>
> You should also be using the three-argument open instead of
> concatenating $filemode and $filename together.
>
> You should actually be able to just pass the arguments to
> open_file on to open directly:
>
> sub open_file
> {
> open @_ or die "Can't open '$filename': $!";

That won't work as the first argument to open is forced into scalar context

$ perl -le'print prototype "CORE::open"'
*;$@

so if @_ contains three elements that becomes:

open 3 or die "Can't open '$filename': $!";

And why is $filename not passed into the subroutine?




John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Perl file handling

am 22.09.2011 18:28:17 von Leo Lapworth

--20cf30780cea477b5604ad8a2fb8
Content-Type: text/plain; charset=ISO-8859-1

On 22 September 2011 09:54, Maggs wrote:

> am trying to open a file but the problem is on the third line
> (open...)
>
> sub open_file {
> local $/ = undef;
> ($filevar, $filemode, $filename) = @_;
> open ($filevar, $filemode . $filename) || die ("Can't open
> $filename");
> }


Are you ok installing/using the Path::Class module? -
https://metacpan.org/module/Path::Class

use Path::Class qw(file);

my $file = file($filename);

my $file_handle = $file->openw();
$file_handle->print("hi");
$file_handle->close();

# or to read
my $file_handle = $file->openr();

# or to get the contents
my $contents = $file->slurp();

print "Contents of " . $file->stringify . " are: \n";
print $contents;

Sorry if that's not actually answering exactly what you asked, but maybe
it'll help.

Leo

--20cf30780cea477b5604ad8a2fb8--

Re: Perl file handling

am 22.09.2011 20:05:02 von timothy adigun

--bcaec520eb3f25434104ad8b88d0
Content-Type: text/plain; charset=ISO-8859-1

Hi Maggs,

I don't know what you really wants to achieve with your codes below:

(open...)

sub open_file {
local $/ = undef;
($filevar, $filemode, $filename) = @_;
open ($filevar, $filemode . $filename) || die ("Can't open
$filename");
}
everytime i run it i get the error: Can't use string ("FILE1") as a
symbol ref while "strict refs" in use.

Any help please on how to sort this out.

I suppose you want to want to open some files using a subroutine, see if the
code below helps, and if not you may have to explain what you really want to
do.


#!/usr/bin/perl -w
use strict;

open_file(@ARGV); # call the subroutine

sub open_file{
foreach (@_){ # iterate on the files to open
open FH,"<",$_ || die "can't open"; # $_ takes the name of the file to
open
while(){ chomp;
print $_,"\n"; # $_ is the line you are printing out
}
close FH || die "can't close file";
}
}

Note: You can call the FH, $fh if you like, but then you must use *my* with
strict in use. You can also use different names for $_, that depends on you.
Regards,
tim

--bcaec520eb3f25434104ad8b88d0--

RE: Perl file handling

am 22.09.2011 20:52:04 von Ken Slater

> -----Original Message-----
> From: timothy adigun [mailto:2teezperl@gmail.com]
> Sent: Thursday, September 22, 2011 2:05 PM
> To: Maggs
> Cc: beginners@perl.org
> Subject: Re: Perl file handling
>
> Hi Maggs,
>
> I don't know what you really wants to achieve with your codes below:
>
>> (open...)
>>
>> sub open_file {
>> local $/ = undef;
>> ($filevar, $filemode, $filename) = @_;
>> open ($filevar, $filemode . $filename) || die ("Can't open $filename");
>> }
>> everytime i run it i get the error: Can't use string ("FILE1") as a
>> symbol ref while "strict refs" in use.
>>
>> Any help please on how to sort this out.
>
> I suppose you want to want to open some files using a subroutine, see
> if the
> code below helps, and if not you may have to explain what you really
> want to
> do.
>
>
> #!/usr/bin/perl -w
> use strict;
>
> open_file(@ARGV); # call the subroutine
>
> sub open_file{
> foreach (@_){ # iterate on the files to open
> open FH,"<",$_ || die "can't open"; # $_ takes the name of the
> file to
> open
> while(){ chomp;
> print $_,"\n"; # $_ is the line you are printing out
> }
> close FH || die "can't close file";
> }
> }
>

> Note: You can call the FH, $fh if you like, but then you must use *my*
> with
> strict in use. You can also use different names for $_, that depends on
> you.
> Regards,
> tim

OP was using trying to use 'open_file' to open one file handle at a time.
Arguments were presumably the file handle variable, mode, and file name.
Your example is very different.

Your code has a precedence problem on the open call.

open FH,"<",$_ || die "can't open";

Try this on a file that does not exist and see what happens.

You need to either place parentheses around the arguments to open or use the
'or' operator.
The '||' operator has higher precedence than the comma. Therefore, it will
only die when $_ evaluates to false.

Also, you should include the reason for the open failure in the message used
by die ($! Or $^E).

HTH, Ken





--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Perl file handling

am 22.09.2011 22:03:59 von Brandon McCaig

On Thu, Sep 22, 2011 at 11:09 AM, John W. Krahn wrote:
> Brandon McCaig wrote:
>>       open @_ or die "Can't open '$filename': $!";
>
> That won't work as the first argument to open is forced into scalar conte=
xt
>
> $ perl -le'print prototype "CORE::open"'
> *;$@
>
> so if @_ contains three elements that becomes:
>
>       open 3 or die "Can't open '$filename': $!";

I didn't think of that. Still, you could pass them directly on
with $_[0], $_[1], and $_[2] (so at least the alias to $_[0] is
intact, though admittedly I know very little of how aliases work
in Perl). :\

> And why is $filename not passed into the subroutine?

An oversight on my part. :) That's what happens when you don't
test the code. ;) Should have been $_[2].


--=20
Brandon McCaig
V zrna gur orfg jvgu jung V fnl. Vg qbrfa'g nyjnlf fbhaq gung jnl.
Castopulence Software ..org>

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Perl file handling

am 23.09.2011 01:54:47 von timothy adigun

--bcaec51f9107f11b3704ad906a0f
Content-Type: text/plain; charset=ISO-8859-1

Hello Maggs,

>>>>>> KS >>>>>Ken Slater wrote:

KS>>OP was using trying to use 'open_file' to open one file handle at a
time.
KS>>Arguments were presumably the file handle variable, mode, and file
name.
KS>>Your example is very different.

I think 'KS' got the heart of what you really want, and in that light try if
this following code could help:


#!/usr/bin/perl -w
use strict;

my @arr=();
my %hash_file=(file_handle=>'fh',file_mode=>'mode',filename=>'n ame');
foreach(sort keys %hash_file){
print "Enter your $_: ";
chomp($hash_file{$_}=);
push @arr,$hash_file{$_};
}
open_file(@arr); # call the subroutine

sub open_file{
no strict "refs"; # use this because filehandle is an expression, that
is it's value
# is the real filehandle, which is considered
a symbolic ref.
# check *perldoc -f open* for more info.
my ($fh,$mode,$name)=@_;
open ($fh,$mode,$name) || die "can't open $!";
while(<$fh>){ chomp;
print $_,"\n"; # $_ takes the line you are printing out
}
close ($fh) || die "can't close file: $!";
}


Regards,
tim

--bcaec51f9107f11b3704ad906a0f--

Re: Perl file handling

am 23.09.2011 14:10:45 von Maggs

On Sep 23, 1:54=A0am, 2teezp...@gmail.com (timothy adigun) wrote:
> Hello Maggs,
>
> >>>>>> KS >>>>>Ken Slater wrote:
>
> KS>>OP was using trying to use 'open_file' to open one file handle at a
> time.
> KS>>Arguments were presumably the file handle variable, mode, and =A0file
> name.
> KS>>Your example is very different.
>
> I think 'KS' got the heart of what you really want, and in that light try=
if
> this following code could help:
>
>
> #!/usr/bin/perl -w
> use strict;
>
> my @arr=3D();
> =A0 =A0my %hash_file=3D(file_handle=3D>'fh',file_mode=3D>'mode',filena me=
=3D>'name');
> =A0 =A0 foreach(sort keys %hash_file){
> =A0 =A0 =A0 =A0print "Enter your $_: ";
> =A0 =A0 =A0 =A0 =A0chomp($hash_file{$_}=3D);
> =A0 =A0 =A0 push @arr,$hash_file{$_};
> =A0 =A0 }
> =A0 open_file(@arr); =A0# call the subroutine
>
> =A0 sub open_file{
> =A0 =A0 no strict "refs"; =A0# use this because filehandle is an expressi=
on, that
> is it's value
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0# is the r=
eal filehandle, which is considered
> a symbolic ref.
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0# check *p=
erldoc -f open* for more info.
> =A0 =A0 =A0 =A0 =A0my ($fh,$mode,$name)=3D@_;
> =A0 =A0 =A0open ($fh,$mode,$name) || die "can't open $!";
> =A0 =A0 =A0 =A0while(<$fh>){ chomp;
> =A0 =A0 =A0 =A0 =A0 =A0print $_,"\n"; =A0 # $_ takes the line you are pri=
nting out
> =A0 =A0 =A0 =A0}
> =A0 =A0 =A0close ($fh) || die "can't close file: $!";
> =A0 }
>

>
> Regards,
> tim



Hello brandon, am trying to create a simple metasearch engine, so i
have a file that has different words (and links) from different search
engines (e.g. google, yahoo), so what am trying to do is open the file
and retrieve the word which equal to the word entered in the search
text box. The next two subroutines read and write from the file, like
this:

sub read_file{
local ($filevar) =3D @_;
<$filevar>;
}

sub read_file{
local($filevar, $line) =3D @_;
print $filevar ($line);
}

so that the results from the files are displayed. So far these two
subroutines dont give any error, its just the one line.


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Perl file handling

am 23.09.2011 18:41:03 von Uri Guttman

>>>>> "M" == Maggs writes:

M> sub read_file{
M> local ($filevar) = @_;

don't use local for that (or for much else). use my. local is meant now
only for special cases with dynamic scoping.

M> <$filevar>;
M> }

why do you need a whole sub to read a line? just <$filevar> does the
same thing!

M> sub read_file{
M> local($filevar, $line) = @_;
M> print $filevar ($line);
M> }

and you have two subs with the same name doing different things. very
confusing and of course only one will be found by perl. the second one
should be called write_file. in neither case do you show the open
calls.

given what you are calling them, use File::Slurp which has read_file and
write_file subs which do all the work you seem to want here. much
cleaner than your code.

uri

--
Uri Guttman -- uri AT perlhunter DOT com --- http://www.perlhunter.com --
------------ Perl Developer Recruiting and Placement Services -------------
----- Perl Code Review, Architecture, Development, Training, Support -------

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/