chromatic wrote:
What's the best way, in your estimation, to explain to novice Perl programmers that, given the vagaries and heuristics of S_intuit_method in toke.c, it's often easier to reason about the local and global effects of any individual unit of code if there are no barewords?

Sure, but there are even more important places where this issue arises. See below.

(I can count on my fingers the number of people who may be able to explain all eight rules for S_intuit_method without having to consult the code as a refresher, and I might be overestimating the number of people so qualified. If anyone, you're one of them, but I don't count on having all novices as experienced or ready to understand in full as you.)

Here, take a shot at it yourself. ☻ Your goal is to uncomment just one from each set of sorted alternatives to produce this exact output:

fileno is 2 fileno is 2 That's all, folks!
Here’s the code:
sub new { die "$0: main::new() sub called\n"; } sub Class { die "$0: main::Class() sub called\n"; } ### PICK EXACTLY ONE OF: #1# local *new ; #2# local *new = Class new ; #3# local *new = Class->new() ; #4# local *new = Class::->new() ; #5# local *new = new Class ; #6# local *new = new Class:: ; ### PICK EXACTLY ONE OF: #1# open( new, "> &=STDERR") || die; #2# open( new, "> &STDERR") || die; #3# open( new, ">& STDERR") || die; #4# open( new, ">&", *STDERR) || die; #5# open( new, ">&=STDERR") || die; #6# open(*new, ">&=STDERR") || die; #7# open(*new, ">&", *STDERR) || die; my $fd = fileno(*new) // die "no fileno"; die "wrong fileno" unless $fd == 2; my $output = "fileno is $fd\n"; syswrite(*main::STDOUT, $output, length($output)); ### PICK EXACTLY ONE OF: #1# (print new $output ) || die; #2# (print "new" $output ) || die; #3# (print *new $output ) || die; #4# (print ::new $output ) || die; #5# (print {*new} $output ) || die; ### PICK EXACTLY ONE OF: #1# close( new ) ? done() : die "can't close new: $!"; #2# close( new::) ? done() : die "can't close new: $!"; #3# close( "new" ) ? done() : die "can't close new: $!"; #4# close( *new ) ? done() : die "can't close new: $!"; #5# close( ::new ) ? done() : die "can't close new: $!"; #6# close(*::new ) ? done() : die "can't close new: $!"; sub done { print "That's all, folks!\n"; } package Class; sub new { require "IO/Handle.pm"; return IO::Handle::->new(); }
Good luck. :)

This isn't about political correctness. It's about reducing the possibility of error in the same way that explaining that always, always, always adding a space between the file open mode and the filename in the two-argument form is as much a pattern for people to emulate as using the three-argument form.
Yes, ok: that’s sound advice. One problem is people are unclear on what a mode even is. See all the flailing above.
You know as well as anyone that novices tend to emulate examples without understanding them fully.
There are something like 650 uses of vintage filehandles in the standard documentation set, and perhaps 400 such uses in the Camel. What do you propose to do, change all those to meet the new purity laws? We already had handle autovivification in 5.6.1, and didn’t see fit to do so then. Has something changed since then? Or was that a terrible blunder? And what should be done in future? You perceive this weighs on my mind.

And what do you do when a user comes to you unhappy that the old standard copy pattern:

print OUTPUT while <INPUT>;
Has no corresponding clean translation? How do you explain that one to them? There is no nice story here: lexical filehandles can too easily break several standard practices that people have come to rely on more than they realize. It is never a pleasant task to explain these strange failures that can result.

And even if the thousand or so uses of vintage filehandles were expunged from the online docs and the Camel (which I personally find to be a terrifically intimidating amount of work — which I do not care to sign myself up to!), what then do you do about the millions of uses of them in existing code that are already out there? Ban them? The current doc policy seems to be to remove all mention of things “we don’t like”; how does that serve the public good?

Encouraging them to prefer constructs where, for example, the lack of an invisible character has no potential security flaws, seems to me to be more useful.
Security flaws? Don’t you think that’s unnecessarily overstating things? That’s like saying that the old rename script has security flaws:
$op = shift() || die; for (@ARGV) { $was = $_; eval $op; die if $@; rename($was, $_) || die "rename: $!" unless $was eq $_; }
The point here is that if you are allowing untrusted antagonists to specify the arguments to your syscalls, then you have bigger problems than mode bits.

That said, I was aghast to find this embarrassing silliness still in perlfunc:

If you want to select on many filehandles, you may wish to write a subroutine like this:
sub fhbits { my(@fhlist) = split(' ',$_[0]); my($bits); for (@fhlist) { vec($bits,fileno($_),1) = 1; } $bits; } $rin = fhbits('STDIN TTY SOCK');
I of course fixed it to read what it should have read since oh, probably perl4 or so:
sub fhbits { my @fhlist = split(" ", $_[0]); my $bits ; for (@fhlist) { vec($bits, fileno($_), 1) = 1; } return $bits; } $rin = fhbits(*STDIN, *TTY, *SOCK);
Filehandles seem to me to be the least of several worrisome bareword issues. In front of that concern come not just bareword strings but most especially an agonizing confusion as to what is and what is not a subroutine call, a method invocation, or even a class name. Doesn’t that bother you?

Used reasonably, vintage filehandles work perfectly well. I’m not sure the same can be said of those others. One needn’t resort to such games as this one:

no strict; no warnings; no less tricksy; foo(lish); his::bar(tab); silly->stuff; come on, please give up; package UNIVERSAL; sub AUTOLOAD { print "I am masquerading as $AUTOLOAD(@_)\n" }
to realize there’s a massively bigger bareword problem lurking right in front of us than that of filehandles alone. All the various multiple‐choice alternatives in my long code segment above should have by now made that starkly clear.

In reply to Re^4: unquoted string error??!! by tchrist
in thread unquoted string error??!! by aji

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.