pg has asked for the wisdom of the Perl Monks concerning the following question:

I was thinking how safe Perl handles addresses and objects. Well, it turned out to be very safe, Perl has a strict checking. This, in a way, revealed to me, how Perl handles and keeps track of objects it loaded.
@a = (1,2,3,4); $a = \@a; $a =~ s/ARRAY/HASH/; print $a, "\n"; print $#{keys %{$a}}, "\n"; # print out -1, very nice $b = {"a" => 1, "b" => 2}; $b =~ s/HASH/ARRAY/; print $b, "\n"; print $#{$b}; # print out -1, very nice
Then, I was thinking that this is not good enough. It will be more nice, if Perl can explicitly warn me. What can I do? so I added "use strict;" at the begining. It worked in the way I expected, my dear Perl complained that I was use strings as ref's.

Replies are listed 'Best First'.
Re: trick or treat
by Zaxo (Archbishop) on Nov 14, 2002 at 06:41 UTC

    You stringify $a and $b when you bind them to a substitution. That removes their reference magic, converting them to strings. When you try to dereference them two lines later, the operation fails under strict, but succeeds without strict by taking the string as a symbolic reference and finding no such structure.

    Are you trying to convert an array ref to a hash ref with that? The string you see when printing a reference is generated - it isn't the actual form of a live reference.

    Minor nit - avoid $a and $b as variables. They are sacred to sort.

    Update: To convert hard array references to hash references, and vice versa, you need to convert the underlying array or hash:

    my $foo = [1..4]; print $foo, $/; $foo = {@$foo}; print $foo, $/; $foo = [%$foo]; print $foo, $/;

    After Compline,
    Zaxo

Re: trick or treat
by diotalevi (Canon) on Nov 14, 2002 at 06:38 UTC

    You've misunderstood. A stringified reference isn't a reference anymore which means your keys %{$a} after altering the string is entirely meaningless. What you really said was to retrieve the keys from the hash named (approximately) 'HASH(0x12345)' which would lookl like my %HASH(0x12345) if that were valid perl code. In effect you're just exercising symbolic references without realizing it. There's absolutely no magic to a string that looks like "ARRAY(0x12345)". It means *nothing* (well it does but you don't normally care) to you except that the specific 'thing' located at the address 0x12345 is an array. The issue is you somehow thought that altering the string representation of a reference actually changes something about the reference. It doesn't - you actually threw the reference away during your process. Somewhat like taking a picture, altering the negative to include your friend in the picture doesn't actually mean your friend *is* in the picture. You might try using Data::Dumper on the reference prior to your s/// op and then after. You'll notice that you stomped all over it and turned it into something entirely different (just a string)

    __SIG__ use B; printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B::svref_2object(sub{})->OUTSIDE;