develooper Front page | perl.perl5.porters | Postings from December 2007

Re: "strict refs" not strict enough

Thread Previous | Thread Next
From:
Michael G Schwern
Date:
December 29, 2007 13:59
Subject:
Re: "strict refs" not strict enough
Message ID:
4776C333.2040603@pobox.com
Mark Jason Dominus wrote:
>> Mark Jason Dominus wrote:
>>> I have been thinking about this for a long time, and it has often
>>> seemed to me that "strict refs" was not as helpful as it could be.
>> I agree with the problem you've outlined, in theory, but I worry about one
>> thing...
> 
> I agree that it is worrisome.
> 
>> Now instead of:
>>
>> 	print "Blah blah $foo blah blah";
>>
>> I need:
>>
>> 	printf "Blah blah %s blah blah",
>> 		ref $foo ? ref2string($foo) : $foo;
>>
>> Or I risk a run-time error.
> 
> You could make the same argument about dereferencing.  How about it?
> You want to write
> 
>         $n_elements = @$aref;
> 
> but if you are using "strict refs" you have to put instead:
> 
>         $n_elements = ref($aref) ? @$aref : .... ;
> 
> or you risk a run-time error.  
>
> But presumably you don't do this, and you don't let it prevent you
> from using "strict refs" either.  So why are the two situations
> different?  (This is not a rhetorical question.)

Ok, good question.  I had to put a little thought into it.

Because both stringification and interpolation are considered a safe, reliable
operations.  And they are in that nothing really bizarre is going to happen,
at worst you get some weird output which you see and fix or an uninitialized
value warning.

$ perl -wle '$foo = [];  print "$foo"'
ARRAY(0x1801180)

$ perl -wle '$foo = undef;  print "$foo"'
Use of uninitialized value in string at -e line 1.

So A) not particularly harmful and B) they give an indication of a problem
combined with C) considered safe.  And it's arguable whether or not
stringifying the reference was intended or not, so it's questionable if
throwing an error actually caught a mistake.

Trying to dereference J Random Scalar is not safe.  At best you get a silent
dereference to an undefined, undeclared list.

$ perl -wle '$aref = "arglebarble";   print scalar @$aref;'
0

At worst you wind up referencing some other variable that happened to have the
same name as the contents of $aref which can wind up doing all sorts of fun
things.  I'm sure I could come up with some fun security hole, too.

So it's A) harmful and B) silent, a very bad combination.

Symbolic refs are also generally not useful as they only work on globals.
Most folks use lexicals.  Not only are globals involved, blowing out
encapsulation, but you can't even tell WHICH global is involved without
executing the program.

I suppose there's a final, subjective argument.  I do tend to write things like:

	print $scalar;

just to find out what's in that $scalar and it would suck if it suddenly
started blowing up and I have to write out

	print to_string $scalar;

just to look at a scalar.  Again, it comes back to the "everything stringifies
safely" Perl assumption.

Whereas the handful of times I use symbolic refs it's all very careful and
obscure (aliasing).


-- 
I have a date with some giant cartoon robots and booze.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About