Ask a Question related to PERL Miscellaneous, Design and Development.
-
synthespian #1
@_ in subroutine corrupts data?
hello --
I can find no reasonable explanation for this behavior. Not theat
there's isn't one (a trivial one at that), but I am having a hard time
finding the reason for this:
#!/usr/bin/perl
@array = subthis(1, 2, 3, 4);
sub subthis {
@array = @_;
foreach (@array) {
print "$array[$_]\n";
}
return (@array);
}
print "Finished\n";
$ perl subrout2.pl
2
3
4
Finished
Whatever happened to the "1"?
Is this behavior to be expected? Why?
I get the same response in Perl 5.6 and 5.8
TIA
Henry
synthespian Guest
-
Contribute 3 corrupts filenames
After several years mixing and matching DreamWeaver and FrontPage, I am keen to get all my authors off of FrontPage (which we get FOC) - I can't... -
Director Corrupts Display
Has anyone else had this problem, when I'm working Director 8.5.1 and have the vector shape window and working on a vector, suddenly the vector image... -
move_uploaded_file() corrupts some files
The move_uploaded_file() function is very quirky. I want to allow users to upload images to the Web site. Here is the code: ... -
form corrupts when sorted
I have a master form that uses tab controls. There are 7 tabs which are attached to subforms When I sort the first subform by the last column... -
DWMX corrupts file
I have a .cfm file with the following lines: </td> </cfloop> </tr> </cfloop> When I open the file in DWMX it changes to: </td> </tr></cfloop> -
Dave Benjamin #2
Re: @_ in subroutine corrupts data?
In article <bkb5d9$p90ge$1@ID-78052.news.uni-berlin.de>, synthespian wrote:
You are looping through the values in @array, and then indexing the array> I can find no reasonable explanation for this behavior. Not theat
> there's isn't one (a trivial one at that), but I am having a hard time
> finding the reason for this:
>
> #!/usr/bin/perl
>
> @array = subthis(1, 2, 3, 4);
>
> sub subthis {
>
> @array = @_;
> foreach (@array) {
> print "$array[$_]\n";
> }
> return (@array);
> }
>
> print "Finished\n";
>
> $ perl subrout2.pl
> 2
> 3
> 4
>
> Finished
>
> Whatever happened to the "1"?
based on those values. In other words, this is what you're printing:
$array[1]
$array[2]
$array[3]
$array[4]
Since arrays are 0-indexed, you are getting three values and an undefined
fourth value. I think what you meant to say was:
print "$_\n";
Instead of:
print "$array[$_]\n";
Dave
--
..:[ dave benjamin (ramenboy) -:- [url]www.ramenfest.com[/url] -:- [url]www.3dex.com[/url] ]:.
: d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :
Dave Benjamin Guest
-
Sam Holden #3
Re: @_ in subroutine corrupts data?
On Wed, 17 Sep 2003 23:28:39 -0300, synthespian <synthespian@uol.com.br> wrote:
you are missing use strict; and use warnings; (or -w).> hello --
>
> I can find no reasonable explanation for this behavior. Not theat
> there's isn't one (a trivial one at that), but I am having a hard time
> finding the reason for this:
>
> #!/usr/bin/perl
That will set $_ to 1, then 2, then 3, then 4.>
> @array = subthis(1, 2, 3, 4);
>
> sub subthis {
>
> @array = @_;
> foreach (@array) {
Since arrays start at element 0 (well, in sane code anyway) that will> print "$array[$_]\n";
print the second element when $_ is 1, the third when $_ is 2, the
fourth when $_ is 3, and the fifth when $_ is 4.
Notice the blank line, that's $array[4] which is undef.> }
> return (@array);
> }
>
> print "Finished\n";
>
> $ perl subrout2.pl
> 2
> 3
> 4
>
You didn't print it.> Finished
>
>
> Whatever happened to the "1"?
Yes. Values aren't the same an indexes.> Is this behavior to be expected? Why?
--
Sam Holden
Sam Holden Guest
-
Chris Dutton #4
Re: @_ in subroutine corrupts data?
"synthespian" <synthespian@uol.com.br> wrote in message
news:bkb5d9$p90ge$1@ID-78052.news.uni-berlin.de...On each iteration $_ contains an actual element of the array, not just the> #!/usr/bin/perl
>
> @array = subthis(1, 2, 3, 4);
>
> sub subthis {
>
> @array = @_;
> foreach (@array) {
index.
This should be written: print "$_\n";> print "$array[$_]\n";
As it is, you're using the item to do a look-up on the array. You've
already got this via foreach. The fact that you're getting anything close
to a correct output is...
.... that the items in the array are (for the most part) valid indices for> }
> return (@array);
> }
>
> print "Finished\n";
>
> $ perl subrout2.pl
> 2
> 3
> 4
that array, except that arrays in Perl begin with index zero, and your array
doesn't contain zero.
Also, by using @array in the "main" scope of your program, and inside the
"subthis" subroutine, your "@array = @_" line is always going to overwrite
the @array in the main scope.
The following does not have this problem.
#!/usr/bin/perl
@array = subthis(1, 2, 3, 4);
sub subthis {
my @array = @_;
foreach my $item (@array) {
print "$item\n";
}
return @array;
}
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system ([url]http://www.grisoft.com[/url]).
Version: 6.0.512 / Virus Database: 309 - Release Date: 8/19/2003
Chris Dutton Guest
-
synthespian #5
Re: @_ in subroutine corrupts data?
Sam Holden wrote:
Yes, it's obvious! Thanks to you and Chris Dutton for taking the time.> On Wed, 17 Sep 2003 23:28:39 -0300, synthespian <synthespian@uol.com.br> wrote:
>>>>hello --
>>
>> I can find no reasonable explanation for this behavior. Not theat
>>there's isn't one (a trivial one at that), but I am having a hard time
>>finding the reason for this:
>>
>>#!/usr/bin/perl
>
> you are missing use strict; and use warnings; (or -w).
>
>>>>@array = subthis(1, 2, 3, 4);
>>
>>sub subthis {
>>
>> @array = @_;
>> foreach (@array) {
>
> That will set $_ to 1, then 2, then 3, then 4.
>
>>>> print "$array[$_]\n";
>
> Since arrays start at element 0 (well, in sane code anyway) that will
> print the second element when $_ is 1, the third when $_ is 2, the
> fourth when $_ is 3, and the fifth when $_ is 4.
>
I thought that what would be set to $_ was the /number/ of elements in
@array, and not 1, 2, 3, 4, and that this number would start at 0.
Like Dave said, "Since arrays are 0-indexed, you are getting three
values and an undefined
fourth value. I think what you meant to say was:
print "$_\n";
Instead of:
print "$array[$_]\n";
So this is about context, is it? $_ will be the placeholder for an
array indexed when $array[$_], otherwise it is not 0-indexed, that is,
is $_ in the case of print "$_\n" evaluating to the number of elements?
Or is it a placeholder for the /elements/ themselves?
What's up with this (perceived) inconsistency?
Thanks for answering.
Regs,
Henry
synthespian Guest
-
synthespian #6
package problem? [was Re: @_ in subroutine corrupts data?]
While we're on this, it got weird with "strict" and "warnings". Why?
@arrayb = subthat(1, 2, 3, 4);
sub subthat {
@arrayb = @_;
foreach (@arrayb) {
print "$_\n";
}
}
print "Finished\n";
$ perl subrout3.pl
Global symbol "@arrayb" requires explicit package name at subrout3.pl
line 5.
Global symbol "@arrayb" requires explicit package name at subrout3.pl
line 9.
Global symbol "@arrayb" requires explicit package name at subrout3.pl
line 10.
Execution of subrout3.pl aborted due to compilation errors.
TIA
Henry
synthespian Guest
-
Sam Holden #7
Re: package problem? [was Re: @_ in subroutine corrupts data?]
On Thu, 18 Sep 2003 00:41:30 -0300, synthespian <synthespian@uol.com.br> wrote:
perldoc strict> While we're on this, it got weird with "strict" and "warnings". Why?
>
>
> @arrayb = subthat(1, 2, 3, 4);
>
> sub subthat {
> @arrayb = @_;
> foreach (@arrayb) {
> print "$_\n";
> }
> }
>
> print "Finished\n";
>
> $ perl subrout3.pl
> Global symbol "@arrayb" requires explicit package name at subrout3.pl
> line 5.
> Global symbol "@arrayb" requires explicit package name at subrout3.pl
> line 9.
> Global symbol "@arrayb" requires explicit package name at subrout3.pl
> line 10.
> Execution of subrout3.pl aborted due to compilation errors.
The section marked "strict vars" is the relevant bit.
--
Sam Holden
Sam Holden Guest
-
Iain Truskett #8
Re: @_ in subroutine corrupts data?
* synthespian <synthespian@uol.com.br>:
[...]> So this is about context, is it? $_ will be the placeholder for an
> array indexed when $array[$_], otherwise it is not 0-indexed, that is,
> is $_ in the case of print "$_\n" evaluating to the number of
> elements? Or is it a placeholder for the /elements/ themselves?There's no inconsistency. In a loop such as:> What's up with this (perceived) inconsistency?
foreach (@array) {
...
}
$_ is set to each element of the array in turn. At no point does $_
contain an array index or the array size except by mathematical
coincidence (that is, the numbers happen to be the same).
The following code should illustrate the point (yes, it's mostly your
code, I just tweaked what it prints and declared some variables and give
it different input):
#!/usr/bin/perl
my @words = subthis( "hello", "xyzzy", "plugh" );
sub subthis {
my @array = @_;
foreach (@array) {
print "$_\n";
}
return @array;
}
cheers,
--
Iain.
Iain Truskett Guest
-
Chris Dutton #9
Re: package problem? [was Re: @_ in subroutine corrupts data?]
"synthespian" <synthespian@uol.com.br> wrote in message
news:bkb9kv$qum8m$1@ID-78052.news.uni-berlin.de...As I mentioned in my earlier reply, when you assign to @arrayb in your> While we're on this, it got weird with "strict" and "warnings". Why?
>
>
> @arrayb = subthat(1, 2, 3, 4);
>
> sub subthat {
> @arrayb = @_;
> foreach (@arrayb) {
> print "$_\n";
> }
> }
>
> print "Finished\n";
>
> $ perl subrout3.pl
> Global symbol "@arrayb" requires explicit package name at subrout3.pl
> line 5.
subroutine, you're not automatically creating a new array. Rather you're
assigning to the @arrayb that's already in the "main" package. Now, while
you can do this, it's not advisable since you can get unexpected results.
You can use the "my" keyword to create a new array inside the subroutine
which has the same name as one in the outer scope.
@arrayb = subthat(1, 2, 3, 4);
sub subthat {
my @arrayb = @_;
foreach (@arrayb) {
print "$_\n";
}
# and I presume from your previous subroutine,
# and how this one is used, that you want @arrayb
# returned.
return @arrayb;
}
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system ([url]http://www.grisoft.com[/url]).
Version: 6.0.512 / Virus Database: 309 - Release Date: 8/19/2003
Chris Dutton Guest
-
Chris Dutton #10
Re: @_ in subroutine corrupts data?
"synthespian" <synthespian@uol.com.br> wrote in message
news:bkb8j5$rjcqj$1@ID-78052.news.uni-berlin.de...To get the number of elements in an array, assign it to a scalar, like so:> Yes, it's obvious! Thanks to you and Chris Dutton for taking the time.
> I thought that what would be set to $_ was the /number/ of elements in
> @array, and not 1, 2, 3, 4, and that this number would start at 0.
my @someArray = (1,2,3,4);
my $lengthOfArray = @someArray;
print "$lengthOfArray\n";
# prints:
# 4
$_ is just a helpful timesaver. It can be a shortcut in that many of Perl's> So this is about context, is it? $_ will be the placeholder for an
> array indexed when $array[$_], otherwise it is not 0-indexed, that is,
> is $_ in the case of print "$_\n" evaluating to the number of elements?
> Or is it a placeholder for the /elements/ themselves?
built-ins use it if no argument is provided. For instance, "print;" is
equivalent to "print $_;".
In the foreach loop, $_ serves as a shortcut to each element of the array.
This can be easily replaced with a more meaningful name if your goal is
long-term maintainability.
foreach (@foo) { print }
is equivalent to:
foreach my $item (@foo) { print $item }
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system ([url]http://www.grisoft.com[/url]).
Version: 6.0.512 / Virus Database: 309 - Release Date: 8/19/2003
Chris Dutton Guest
-
Tad McClellan #11
Re: @_ in subroutine corrupts data?
synthespian <synthespian@uol.com.br> wrote:
> Sam Holden wrote:>> On Wed, 17 Sep 2003 23:28:39 -0300, synthespian <synthespian@uol.com.br> wrote:
>>>>> I can find no reasonable explanation for this behavior.
See the "Foreach Loops" section in perlsyn.pod.
>>>>>>@array = subthis(1, 2, 3, 4);
>>>
>>>sub subthis {
>>>
>>> @array = @_;
>>> foreach (@array) {
>>
>> That will set $_ to 1, then 2, then 3, then 4.
>>
>>>>>>> print "$array[$_]\n";
>>
>> Since arrays start at element 0 (well, in sane code anyway) that will
>> print the second element when $_ is 1, the third when $_ is 2, the
>> fourth when $_ is 3, and the fifth when $_ is 4.
>>
> Yes, it's obvious!> So this is about context, is it?
If you mean list context vs. scalar context, then no, this
is not about context.
This is about how foreach loops work in Perl.
> $_ will be the placeholder for an
> array indexed when $array[$_], otherwise it is not 0-indexed, that is,
You can manipulate lists using foreach without any explicit
indexing at all.
> is $_ in the case of print "$_\n" evaluating to the number of elements?
> Or is it a placeholder for the /elements/ themselves?
The correct term is "alias" rather than "placeholder".
> What's up with this (perceived) inconsistency?
It sounds like you haven't read up on the operation of foreach.
--
Tad McClellan SGML consulting
[email]tadmc@augustmail.com[/email] Perl programming
Fort Worth, Texas
Tad McClellan Guest
-
Tad McClellan #12
Re: package problem? [was Re: @_ in subroutine corrupts data?]
synthespian <synthespian@uol.com.br> wrote:
> While we're on this, it got weird with "strict" and "warnings". Why?
use warnings has nothing to do with it, there are no warning
messages below.
> @arrayb = subthat(1, 2, 3, 4);> $ perl subrout3.pl
> Global symbol "@arrayb" requires explicit package name at subrout3.pl
> line 5.
When you put "use strict" in your program, you are making this
promise to perl:
I will declare all of my variables before I use them.
If you break your promise, perl will refuse to run your program.
You are using @arrayb without declaring it, you've broken your promise.
So, either declare the variable:
my @arrayb = subthat(1, 2, 3, 4);
or use an explicit package name:
@main::arrayb = subthat(1, 2, 3, 4);
--
Tad McClellan SGML consulting
[email]tadmc@augustmail.com[/email] Perl programming
Fort Worth, Texas
Tad McClellan Guest



Reply With Quote

