harangzsolt33 has asked for the wisdom of the Perl Monks concerning the following question:
But now let's try this through a reference. Here we create a reference to an LVALUE: MODIFYRR(\3) where sub MODIFYRR { my $REF = $_[0]; $$REF = 1; } Now, do we get an error, because we try to modify the constant 3 ? NO, we don't! Why? Because the moment it created a reference, it also copied 3 in the memory somewhere. And the only way we can access that copy in the memory is through the reference we created. So, we can both read or write that memory location through the reference. And when trying to modify the value through that reference, it is no longer behaving like an lvalue. (In this example, MODIFYRR(\3) we don't even pass a reference to an lvalue; we actually pass a reference to a SCALAR.)
I've read that the ref() function will tell us what a reference is pointing to. For example, if something is a reference to a SCALAR or CODE or HASH or LVALUE or GLOB or whatever. So, that way we can figure out what type the $_[0] argument is. But it does not work! Why? Because we can't just do ref($_[0]) because it's not a reference, so it just returns an empty string, but if we create a reference to $_[0] by saying $REF = \$_[0]; and then try to see what type of reference it is: ref($REF), we only get a few possibilities: If it's a code reference, it will say 'CODE' or if it's a scalar reference, it will say 'SCALAR' but it will never say 'LVALUE' as the documentation claims. Why? Because the moment we try to make a reference to an lvalue, it copies the original lvalue into a scalar and then creates a reference TO THAT SCALAR. So, ref() will always say 'SCALAR' when we test an lvalue. So, I give up! How do you do this?? I want to know if an argument is lvalue or not. :(
#!/usr/bin/perl -w use strict; use warnings; my @S = ('a', 'b', 'c', 1, 2, 3); my $SCALAR = 555; my $SCALAR_REF = \"Hello World"; my $CODE_REF = sub { print "HI"; }; print "\n\n"; my $A = 3; MODIFY($A + 3); print " A = $A \n\n--------------"; # I want to print the TYPE of these arguments: AAA(@S, $SCALAR, $SCALAR + 3, 9999, \444, $SCALAR_REF, $CODE_REF); exit; sub AAA { foreach (@_) { my $REF = \$_; print "\nvalue: $_ \t\t type: ", ref($REF); MODIFYRR($REF); # MODIFY($_); } } sub MODIFY { $_[0] = 1; } sub MODIFYRR { my $REF = shift; $$REF = 1; }
|
---|