Perl Bug or stupidity on my part? - I looked in FAQs and dejanews prior to posting

Z

Zachary Buckholz

I am passing a reference to a hash where the key is a scalar and each
value is a reference to an array to another sub. But unless I use a
subscript like $_[0] I can not get it in the recieving sub. Typically
I can just use $_ when passing one variable;

I am using -w and use strict;

Example of what I am doing:

sub build_hash {
# code to build hash with scalar keys and ref to arrays as values
# each key has three array ref values.
parse_hash($some_ref_to_a_hash);
}

sub parse_hash {
my $some_ref_to_a_hash = $_; # <--- This does not work
}

sub parse_hash {
my $some_ref_to_a_hash = $_[0]; # <--- This WORKS!
}

I scanned deja.com for two days and the FAQ's on my local machine
before posting this.
 
B

Ben Morrow

I am passing a reference to a hash where the key is a scalar and each
value is a reference to an array to another sub. But unless I use a
subscript like $_[0] I can not get it in the recieving sub. Typically
I can just use $_ when passing one variable;

No you can't.
I am using -w and use strict;
Good.

Example of what I am doing:

sub build_hash {
# code to build hash with scalar keys and ref to arrays as values
# each key has three array ref values.
parse_hash($some_ref_to_a_hash);
}

sub parse_hash {
my $some_ref_to_a_hash = $_; # <--- This does not work

and never will. Nothing in the documentation implies it should.
}

sub parse_hash {
my $some_ref_to_a_hash = $_[0]; # <--- This WORKS!

because this is the way you get at subroutine arguments.
}

I scanned deja.com for two days and the FAQ's on my local machine
before posting this.

....but didn't get as far as the third paragraph of perldoc perlsub?

You can't just make shit up and expect the machine to know what you
mean.

Ben
 
T

Tad McClellan

[ re your Subject: the 2nd one. :) ]

Typically


That implies that you have done it successfully before.

I can just use $_ when passing one variable;


How did you ever get that to work?

sub parse_hash {
my $some_ref_to_a_hash = $_; # <--- This does not work
}


Of course not.

The scalar variable named $_ does not have any connection to
function arguments.

The function arguments are in the _array_ named @_.

sub parse_hash {
my $some_ref_to_a_hash = $_[0]; # <--- This WORKS!


Right, because you are accessing the 1st element of the @_ array.

Other ways:
my $some_ref_to_a_hash = shift @_;
or
my $some_ref_to_a_hash = shift;
or
my($some_ref_to_a_hash) = @_; # my preference

}

I scanned deja.com for two days and the FAQ's on my local machine
before posting this.


Google is the 3rd best resource available.

The Perl FAQs are the 2nd best resource available.

The std docs are the best resource available:

perldoc perlsub

Any arguments passed in show up in the array @_. Therefore, if
you called a function with two arguments, those would be stored in
$_[0] and $_[1].


Wherein there are also numerous examples of different ways of
accessing the function's arguments, none of them using the
scalar variable named $_.


$a has nothing to do with $a[0].

$_ has nothing to do with $_[0].

Notwithstanding the funny-looking name.
 
W

Walter Roberson

:You can't just make shit up and expect the machine to know what you
:mean.

Yes you can -- this is Perl, after all ;-)
 
G

gnari

Zachary Buckholz said:
I am passing a reference to a hash where the key is a scalar and each
value is a reference to an array to another sub. But unless I use a
subscript like $_[0] I can not get it in the recieving sub. Typically
I can just use $_ when passing one variable;

others have replied to your question, but I have a question for you:

can you show us a few examples where you use $_ ?
(where it works, I mean)

gnari
 
E

Eric Amick

I am passing a reference to a hash where the key is a scalar and each
value is a reference to an array to another sub. But unless I use a
subscript like $_[0] I can not get it in the recieving sub. Typically
I can just use $_ when passing one variable;

The only way I can picture that working is if $_ happened to have the
same value as the argument you passed. With $_ normally being global,
it would appear to work as you describe. As others have already pointed
out, it certainly doesn't work in general.
 
Z

Zachary Buckholz

Thank you to eveyone that replied.

I appologize for not carefully reviewing my post prior to posting, in
fact I was not using $_. I probably tried it a few times. I was using
@_

When running scripts some times I get the following error.
Scalar value @_[0] better written as $_[0]

I went back through a lot of my scripts with a quick grep looking to
find an instance when I used just $_ and noticed even in my old old
old code I was indeed using $_[0] never just $_

Thank You



Eric Amick said:
I am passing a reference to a hash where the key is a scalar and each
value is a reference to an array to another sub. But unless I use a
subscript like $_[0] I can not get it in the recieving sub. Typically
I can just use $_ when passing one variable;

The only way I can picture that working is if $_ happened to have the
same value as the argument you passed. With $_ normally being global,
it would appear to work as you describe. As others have already pointed
out, it certainly doesn't work in general.
 
A

Andy Baxter

At earth time Sun, 11 Jan 2004 20:19:59 -0800, the following transmission
was received from the entity known as Zachary Buckholz:
Thank you to eveyone that replied.

I appologize for not carefully reviewing my post prior to posting, in
fact I was not using $_. I probably tried it a few times. I was using
@_

When running scripts some times I get the following error.
Scalar value @_[0] better written as $_[0]

I went back through a lot of my scripts with a quick grep looking to
find an instance when I used just $_ and noticed even in my old old
old code I was indeed using $_[0] never just $_

Thank You

The rule is, if you access an element of an array or hash, then the thing
you are accessing is a scalar value, so you put a $ in front of it.

I.e.
$a is the scalar variable a.
@a is the array variable a (could be entirely different)
%a is the hash a.

and

$a[0] is the first element of array a.
$a{akey} is a value in hash a referenced by key 'akey'

@a[0] and %a{akey} don't have any proper meaning AFAIK.

if $b is a reference to hash a ($b=\%a;), then
$$b{akey} is the same as $a{akey}

also,

$a=@a;

means set scalar var a to the number of elements in array a. (But
maybe better to write this as $a=scalar(@a); to make it clear.)
 
E

Eric Amick

The rule is, if you access an element of an array or hash, then the thing
you are accessing is a scalar value, so you put a $ in front of it.

I.e.
$a is the scalar variable a.
@a is the array variable a (could be entirely different)
%a is the hash a.

and

$a[0] is the first element of array a.
$a{akey} is a value in hash a referenced by key 'akey'

@a[0] and %a{akey} don't have any proper meaning AFAIK.

@a[0] is a valid, though probably unintended, array slice, and is
equivalent to ($a[0]). As already noted, it will generate a warning if
use warnings is in effect.
 
G

G Klinedinst

Other ways:
my $some_ref_to_a_hash = shift @_;
or
my $some_ref_to_a_hash = shift;
or
my($some_ref_to_a_hash) = @_; # my preference

Tad,
I understand that you are assigning list @_ to an unnamed list with
one element, and the element's name is $some_ref_to_a_hash. My
question is why is that your preference? Either of the first would
seem more readable to me b/c you are assigning a single scalar, rather
than assigning the whole list. Do you prefer the other way b/c it is
easier to go back and add more variables in your assignment statement
later if you decide to pass other vars as well?

I don't really know the inner workings of perl but it would seem
that the last option would be more work for the computer(hence slower)
as it either copies values or at least copies pointers to all the
values and then discards all but the first. BTW, I am still a relative
newbie to Perl so I am asking you to learn, NOT to give you a hard
time.

-Greg K.
 
T

Tad McClellan

G Klinedinst said:


Please use the conventional form of attribution in your followups.

I understand that you are assigning list @_ to an unnamed list with


There is no such thing as a named list, so the "unnamed" is
an unnecesary qualification.

@_ is an array, it is not a list. It _contains_ a list though.

Have you seen the Perl FAQ about the difference between
a "list" and an "array"?

The last way given above is a "list assignment". It has a list on
the left and a list on the right. The fact that one or more of
the lists comes from an array is a special case of the general case.

Here is a list assignment with no arrays for example:

my($first, $second, $third) = split /:/;

one element, and the element's name is $some_ref_to_a_hash. My
question is why is that your preference? Either of the first would
seem more readable to me b/c you are assigning a single scalar, rather
than assigning the whole list. Do you prefer the other way b/c it is
easier to go back and add more variables in your assignment statement
later if you decide to pass other vars as well?


That is one of the two reasons that I'd prefer the last way given above.

The other, and more important, reason is that it leaves
the values in @_ intact.

I only remove elements from @_ when I plan to do something else
to all of the elements that remain.

I don't really know the inner workings of perl but it would seem
that the last option would be more work for the computer(hence slower)


Even thinking about such things would be "premature optimization"
in my book.

I don't worry about execution speed.

I worry about the speed of development and maintenance.
 
G

G Klinedinst

Tad McClellan said:
Please use the conventional form of attribution in your followups.

Is the preceding sentence what you were talking about? If not let me
know about what convention I didn't follow and I will gladly follow
it.
Have you seen the Perl FAQ about the difference between
a "list" and an "array"?

I just read through it. Thanks for the recommendation.
The other, and more important, reason is that it leaves
the values in @_ intact.

Ahh, makes sense. Good reason. Thanks for taking the time to answer my
question.

-Greg K.
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top