Re: How to open sub FH when filename is passed to sub?
by chromatic (Archbishop) on May 05, 2002 at 14:30 UTC
|
I'm surprised it gets that far. Please copy and paste the smallest *exact* code that gives you this error -- there are too many syntax errors and typos here for me to understand what you mean.
My guess is that you're trying to open a file with an undefined name. This means that $myhashname has an undefined value. Looking at your argument passing, you probably mean to say:
my $myhashname = shift;.
After that, you're passing two lists, and appear to be attempting to receive them both into two listy variables. That doesn't work -- the first list will slurp up all of the elements. You'll have better luck if you pass references. Reading perlsub and perlreftut may help. | [reply] [d/l] [select] |
Re: How to open sub FH when filename is passed to sub?
by IlyaM (Parson) on May 05, 2002 at 14:24 UTC
|
Add $! into your print and it will show you reason for failure.
unless (cpen (FH, $myhashname)) {
print STDERR "Can not open file\"$myhashname\": $!n\n";
exit;}
BTW much more common ideom for doing same thing (opening file and exiting with error in case of failure) is:
open (FH, $myhashname)
or die "Can not open file\"$myhashname\": $!";
--
Ilya Martynov
(http://martynov.org/)
| [reply] [d/l] [select] |
(jeffa) Re: How to open sub FH when filename is passed to sub?
by jeffa (Bishop) on May 05, 2002 at 15:55 UTC
|
You must be the same person who posted create subroutine. You
really should show us what your requirements are, and most
importantly, what you data looks like. Let's make some up.
Save this in a text file named in_file.txt:
D:Aspartic Acid
E:Glutamic Acid
F:Phenylalanine
G:Glycine
H:Histidine
I:Isoleucine
K:Lysine
L:Leucine
M:Methionine
N:Asparagine
Our requirements will be simple:
- pass a file name ('in_file.txt') to a subroutine that
- opens the file in read mode
- reads one line at a time
- remove trailing newline
- splits the line on a token (':') into two elements
- the first element is a key
- the second element will be the value
- stores the key-value pair in a hash
- returns the hash
- store the returned hash in a new hash
- loop through the hash and print the key-val pairs
Here goes:
#!/usr/bin/perl -w
# always use strict and warnings (-w from above)
use strict;
# 1 and 2
my %new_hash = create_hash('in_file.txt');
# 3
while(my($key,$val) = each %new_hash) {
print "$key => $val\n";
}
sub create_hash {
my $filename = shift;
my %hash;
# 1.1
open(FILE,'<',$filename) or die "can't read $filename: $!";
# 1.2 - you get the point ;)
while (my $line = <FILE>) {
chomp $line;
my($key,$val) = split (':',$line,2);
$hash{$key} = $val;
}
return %hash;
}
Now, at thist point i recommend you go buy and read
Learning Perl. After you get some
basics under your belt, you can then check out
BioPerl and their lengthy
Tutorial.
Good luck!
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)
| [reply] [d/l] |
|
|
Thank you for your help jeffa!
I am a beginner for perl. My new hash keys I can read in from a file, but my values I have to get them from my main hash.Why you use shift? Does it mean it can change different filename everytime you call sub? if it is so, that is what I want.
Please help
| [reply] |
|
|
You are most welcome. Yes, that is exactly why i use
shift. shift returns the first value from an array, in
this case it is the implied array @_ which is used by
Perl to store the arguments passed to a given subroutine.
I could have used this instead:
my $filename = shift @_;
# or even
my ($filename) = @_;
# multiple arguments are best caught this way:
my ($first,$second,$third) = @_;
# but some folks prefer
my $first = shift;
my $second = shift;
my $third = shift;
Most (if not all...)
other languages use an argument list to specify what a
subroutine can be 'passed', as well as a return type
(together these form the 'signature'). For example, in
Java, these:
| [reply] [d/l] [select] |
|
|
Thank you so much jeffa!
I do make my sub hash, it gave me all the result, but it still tell me :
Use of uninitialized value at ./lx line 97.
Use of uninitialized value at ./lx line 97.
total 10 times Use of above context.
my sub like:
sub create_hash {
my $myhashname=shift;
my %myhashname=%_;
my @keys=@_;
unless(open(FH, ">$myhashname") ) {
print STDERR "Cannot open file\"$myhashname\"\n\n";
exit;}
@myhashname{@keys}=@mydnahash{@keys};
while (($k, $v)=each %myhashname){
print FH "$k=>$v, "};
close FH;
return %myhashname;
}
and I call sub like:
my %myeditedhash=
create_hash('myeditedhash',@editedsites, @mydnahash{@editedsites});
print FH "$k=>$v, "}; is line 97.what is wrong? please help. | [reply] [d/l] [select] |
|
|
use strict;
my @array1 = (1,2,3,4);
my @array2 = (5,6,7,8);
my %hash = (
key => 'val',
foo => 'bar',
);
print '=' x 20, "\nwrong way:\n";
wrong1(@array1,@array2);
sub wrong1 {
my (@a1,@a2) = @_;
print "array 1: @a1\n";
print "array 2: @a2\n";
# notice that @a2 is empty
}
print '=' x 20, "\nright way:\n";
right1(\@array1,\@array2);
sub right1 {
my @a1 = @{ shift @_ };
my @a2 = @{ shift @_ };
print "array 1: @a1\n";
print "array 2: @a2\n";
# multiple arrays must be passed in as references
}
print '=' x 20, "\nwrong way:\n";
wrong2(%hash);
sub wrong2 {
my %hash = %_;
while (my($k,$v) = each %hash) {
print "$k => $v\n";
}
# %_ is not special, use @_ instead - always!
}
print '=' x 20, "\nright way:\n";
right2(%hash);
sub right2 {
my %hash = @_;
while (my($k,$v) = each %hash) {
print "$k => $v\n";
}
# a hash is really just a special kind of array
# and yes, multiple hashes must be passed as references too
}
# last - a hash slice
my %slice;
@slice{@array1} = @array2;
print '=' x 20, "\nhash slice:\n";
while (my($k,$v) = each %slice) {
print "$k => $v\n";
}
# and don't creat hash slices inside an subroutine's
# argument list - that is bad bad bad ;)
Good luck, and please read this book: Learning Perl.
jeffa
Cargo Cult Programming - Just say 'NO!' | [reply] [d/l] |
Re: How to open sub FH when filename is passed to sub?
by arunhorne (Pilgrim) on May 05, 2002 at 14:31 UTC
|
Perhaps you need to use my $myhashname=$_; instead of my $myhashname=$;
Your programming style is very different to mine, but if you try to tell us what you method intends to do, it will be possible to give you some working code.
However if you are getting "cannot open file" then $myhashname cannot be a valid filename. Perhaps try putting print $myhashname above the open command to check the filename being passed or use the debugger to find this. Finally, its not clear from your code if you are trying to read from or write to the the file, if you want to write to it your open statement should look this this:
unless (cpen (FH, ">$myhashname")) {
Hope some of this helps, post back with more info if it doesn't.
Arun
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
Then you probably want something like this:
#!/usr/bin/perl -w
use strict;
create_hash('out_file.txt');
sub create_hash {
my $filename = shift;
my %hash;
my @symbol = ('D'..'M');
my @protein = (
'Aspartic Acid',
'Glutamic Acid',
'Phenylalanine',
'Glycine',
'Histidine',
'Isoleucine',
'Lysine',
'Leucine',
'Methionine',
'Asparagine',
);
@hash{@symbol} = @protein;
open(FILE,'>',$filename) or die "can't write $filename: $!";
while(my($key,$val) = each %hash) {
print FILE "$key:$val\n";
}
}
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)
| [reply] [d/l] |