http://www.perlmonks.org?node_id=1026191


in reply to Wrong idioms

Sometimes I get the feeling that simply the look and feel of the code is the reason to do so.

Or maybe just the effort to write the code in the first place. Or missing awareness.

There are many more similar but less obvious cases. For example code that interpolates an array into a double-quoted string depends on the value of $". Code that uses print implicitly uses $\ and $,, and if you use readline (or <$fh>) or chomp you'd better hope nobody messed up your $.

And good thing that $[ is deprecated.

And your seemingly harmless loop while (<>) { } gets an entirely new meaning if $^I is set.

Speaking of <>, did you know that it executes code for you?

$ perl -we 'while (<>) { print }' 'fortune |' To downgrade the human mind is bad theology. -- C. K. Chesterton

So you see there is a whole scale of things you should consider when you want to write truely robust and correct code. But once you start to write your code as

sub do_something { my ($filename, @rest) = @_; return unless defined $filename; # ensure basic sanity: local $/ = "\n"; local $, = ''; local $\ = ''; local $" = ' '; local $@; # we might want to use eval { } }

you get a lot of boilerplate code, and writing Perl stops to be fun.

So you can either leave Perl 5 for good, or decide where on your scale between fun and correctness your code should be. Don't condemn anybody for using a simple truth check instead of defined, but not for failing to reset all used global variables in each routine that could be called from the outside.

Note that Perl 6 drastically reduces the number of global and special variables, and most built-in functions don't depend on them to the same degree as in Perl 5.

Replies are listed 'Best First'.
Re^2: Wrong idioms
by McA (Priest) on Mar 29, 2013 at 21:35 UTC

    Thank your for your comment and insights. Yes, my example is only the tip of the iceberg as you showed very clearly concerning robustness. But I think there is a little difference between allowing a filename of "0" and messing up a default behaviour of perl by changing special variables.

    But anyways: Be sure I don't condemn anybody for how he or she is coding. The only person I do is myself.

    And you have to admit that I haven't used the term error anywhere because it's the right of the programmer to write a function where "0" is not a valid filename in his sence.

    I initiated this thread because on the one handside newcomers are said to study at least top rated CPAN code to learn from it and on the other handside is a framework like a fundament which shouldn't have litte fissures.

    McA

    P.S.: A ++ for showing all the implications while coding in perl5.

Re^2: Wrong idioms
by vsespb (Chaplain) on Mar 29, 2013 at 23:58 UTC

    I think if you try to submit a bug report for a module, saying that it works wrong when you redefine several perl special variables, nobody will agree to fix that. At maximum they will add a note to the specification, that you should not redefine variables.

    But bug with filename '0' is different case. It's a bug, absolutely.

      I think if you try to submit a bug report for a module, saying that it works wrong when you redefine several perl special variables, nobody will agree to fix that.

      But why? It's not wrong to assign a value to those special variables. That's what they are for. If you don't ever assign values to them, there's no reason they'd need to exist at all.

      So, why would somebody reject such a bug report? Maybe because it's unsual that it's done in code that isn't a oneliner.

      But bug with filename '0' is different case. It's a bug, absolutely.

      But one can argue that using 0 as a file name is also unusual.

      What do you think about modules that can't handle file names that contain quotes? Or a newline? Is that also a bug, absolutely? What about not handling non-ASCII file names (for which there seems to be no cross-platform way of handling them corectly)?

      You draw a line and say "not handling non-default $, is not a bug", but you say "not handling 0 filenames is a bug". Based on what criteria do you draw that line? And where do you draw it?

      For the record, I too would consider not handling a filename of 0 a bug, but I lack your perspective on which corner cases need to be handled, and which are OK to ignore.

        Hi moritz,

        Well said. I share your opinion. To your question

        ...you say "not handling 0 filenames is a bug". Based on what criteria do you draw that line?
        I want to give a nucleus for a hopefully intersting discussion. Can it be that user's or programmer's expectation is the driving criteria?

        To stick at the filename example (which shouldn't be in the focus of my thread), years ago nobody expected that filenames containing non-ascii characters would work, but nowadays I'm pretty sure that users expect to be able to write e.g. German umlauts in their filenames.

        Are common expectations (yes, yes, it's very vague) a kind of implicit, unwritten requirement? :-)

        McA

        There is no strict criteria.

        If you don't ever assign values to them, there's no reason they'd need to exist at all.
        if you use it - localize it, and don't call other modules inside scope.

        File::Find uses user's $; and it won't be fixed https://rt.perl.org/rt3/Public/Bug/Display.html?id=116350#txn-1183176

        Sad there is not Perl documentation saying in which case those variables should be localized (or there is?).

        What do you think about modules that can't handle file names that contain quotes?
        bug.

        Or a newline?
        small bug (user is just waiting for troubles with those filenames)

        What about not handling non-ASCII file names
        means module does not support Unicode or specific platform (some perl core modules doest not support unicode - this is the criteria)

        for which there seems to be no cross-platform way of handling them corectly
        It depends on what's "handling". I think there is way to just open files, crossplatform (except non Unicode platforms). Anyway, looks like a bug (if undocumented) or missing feature (if listed as known bugs). btw File::Find has open bugs for it.

        Based on what criteria do you draw that line?
        The big difference, that programmer control perl variables, but does not control user's filenames. Also it depends on what program do. If it just open a one user supplied file - it's one case. If it searches files on disk and opens each of them - even user cannot control filenames, so it should handle (or at least catch an error) any valid filename.

Re^2: Wrong idioms
by Jenda (Abbot) on Apr 01, 2013 at 10:42 UTC

    If you mess with these variables, it's YOUR duty to put them back in order! The code that changes them and leaves them changed is incorrect, not the code that fails to check and/or reset them.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

      Well, if you mess with your caller's variables, I agree. But if you want to use those variables for your own purposes, you can't help but let the callee also see the changed variables (because you can only localize the, not modify them in a lexical scope).

        Don't call then! All advice you ever hear about changes to these variables says "change them only in the smallest possible scope and do not call anything that might expect them to be set to the normal values".

        Most of the variables are not changed too often so I would not sweat about it. The only one I see changed is $/ and the code usually looks like this:

        my $contents = do {local $/; <HANDLE>;}
        or
        my $contents; { local $/; $contents = <HANDLE>; }

        and the code implementing readline() for handles is the only one I would expect to check the value of $/.

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.