Hi
I just made the code and output clearer and added a question.
> You never pass an array or hash, just references to them. It's not even possible to pass arrays or hashes to subroutines.
Thats a matter of interpretation, the behaviour of push @arr, "elem" can be reproduce with prototypes sub name (\@@)
| [reply] [d/l] [select] |
First of all, push is not a subroutine. I'll concentrate on your second example, sub name (\@@).
While it could be a matter of interpretation in general, it's unequivocal in this case because we're talking about the value of $_[0]. The \@ prototype causes a reference to the array to be passed to the sub, not an array. $_[0] contains a reference, not an array. Printing \$_[0] would print a reference to a reference to an array, not a reference to an array.
| [reply] [d/l] [select] |
Push is a CORE:: subroutine which you can override, please check perlsub
> Printing \$_[0] would print a reference to a reference to an array, not a reference to a reference.
well the constant gets always at runtime a reallocated space, while the arrayref doesn't!!!
here a code that makes it hopefully clearer.
UPDATE: no it doesn't, passing a ref to a literal scalar works as wanted!!!
use strict;
use warnings;
sub pr {
print \$_[0]," : ",$_[0],"\t"; # print ref:value of para
}
check(qw/ Scalar 1 /);
check(qw/ Scalarref \1 /);
check(qw/ Array [1,2] /);
check(qw/ Hash {1,2} /);
sub check {
my ($_title_,$type) = @_;
my $_call_ ="pr $type;";
my $code= <<"__EOC";
for (1..3) {
$_call_
print "\\n\\t";
for (1..3) {
$_call_
}
print "\\n";
}
__EOC
print "\n--- $_title_ \n";
print $code;
eval $code;
}
__END__
--- Scalar
for (1..3) {
pr 1;
print "\n\t";
for (1..3) {
pr 1;
}
print "\n";
}
SCALAR(0x81953b0) : 1
SCALAR(0x8190778) : 1 SCALAR(0x8190754) : 1 SCALAR(0x8190778
+) : 1
SCALAR(0x8190754) : 1
SCALAR(0x819076c) : 1 SCALAR(0x8190778) : 1 SCALAR(0x819076c
+) : 1
SCALAR(0x8190778) : 1
SCALAR(0x81953b0) : 1 SCALAR(0x819076c) : 1 SCALAR(0x81953b0
+) : 1
--- Scalarref
for (1..3) {
pr \1;
print "\n\t";
for (1..3) {
pr \1;
}
print "\n";
}
REF(0x8190754) : SCALAR(0x81953ec)
REF(0x8190760) : SCALAR(0x8195428) REF(0x819073c) : SCALAR(0x81
+95428) REF(0x8190760) : SCALAR(0x8195428)
REF(0x819073c) : SCALAR(0x81953ec)
REF(0x81953b0) : SCALAR(0x8195428) REF(0x8190760) : SCALAR(0x81
+95428) REF(0x81953b0) : SCALAR(0x8195428)
REF(0x8190760) : SCALAR(0x81953ec)
REF(0x8190754) : SCALAR(0x8195428) REF(0x81953b0) : SCALAR(0x81
+95428) REF(0x8190754) : SCALAR(0x8195428)
--- Array
for (1..3) {
pr [1,2];
print "\n\t";
for (1..3) {
pr [1,2];
}
print "\n";
}
REF(0x8190754) : ARRAY(0x81953c8)
REF(0x8190724) : ARRAY(0x819073c) REF(0x8190724) : ARRAY(0x8190
+73c) REF(0x8190724) : ARRAY(0x819073c)
REF(0x8190754) : ARRAY(0x819073c)
REF(0x8190724) : ARRAY(0x81953c8) REF(0x8190724) : ARRAY(0x8195
+3c8) REF(0x8190724) : ARRAY(0x81953c8)
REF(0x8190754) : ARRAY(0x81953c8)
REF(0x8190724) : ARRAY(0x819073c) REF(0x8190724) : ARRAY(0x8190
+73c) REF(0x8190724) : ARRAY(0x819073c)
--- Hash
for (1..3) {
pr {1,2};
print "\n\t";
for (1..3) {
pr {1,2};
}
print "\n";
}
REF(0x81953c8) : HASH(0x8154708)
REF(0x8190748) : HASH(0x81953c8) REF(0x8190748) : HASH(0x81953c
+8) REF(0x8190748) : HASH(0x81953c8)
REF(0x8154708) : HASH(0x81953c8)
REF(0x8190748) : HASH(0x8154708) REF(0x8190748) : HASH(0x815470
+8) REF(0x8190748) : HASH(0x8154708)
REF(0x81953c8) : HASH(0x8154708)
REF(0x8190748) : HASH(0x81953c8) REF(0x8190748) : HASH(0x81953c
+8) REF(0x8190748) : HASH(0x81953c8)
| [reply] [d/l] |
Thats a matter of interpretation, the behaviour of push @arr, "elem" can be reproduce with prototypes sub name (\@@)
The prototype is just syntactic sugar for taking a reference (plus extra behaviour, for example enforcing list context), so independently of what it looks like on the caller side, the callee always sees a reference, never the array itself.
| [reply] [d/l] [select] |
prototypes are not only syntactic sugar, they are essential to syntax
print prototype 'CORE::push'; # \@@
| [reply] [d/l] |
Now, what's your question?
Well, why the heck do constants get a new allocated place? Doesn't seem to me as if the compiler does optimisation right! | [reply] |
?? You are not supposed to care one way or the other.
| [reply] |