Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Prohibiting redeclaration of lexicals in inner scope

by JohnLon (Initiate)
on Mar 31, 2003 at 15:31 UTC ( #246950=perlquestion: print w/ replies, xml ) Need Help??
JohnLon has asked for the wisdom of the Perl Monks concerning the following question:

In Java and C++ (or at least Sun CC with +w) its an error to define the same variable at a narrower scope than an existing definition.
eg bad.c { int a=1; { int a=1; } }

eg CC +w bad.c "c.c", line 7: Warning: i hides the same name in an outer scope.

If I have the below in perl how do I persuade perl to reject this as I can for C++ and Java ?

my $var=1; { my $var=1; }
Is there a cpan module that supports this if its not possible in the core tool.

Even warnings and strict turned on don't seem to help.

Comment on Prohibiting redeclaration of lexicals in inner scope
Select or Download Code
Re: Prohibiting redeclaration of lexicals in inner scope
by hardburn (Abbot) on Mar 31, 2003 at 15:42 UTC

    That's a feature, not a bug. Do you have a specific reason why it should be disallowed?

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

      Not suggesting its a bug - but I would definitely like to enforce this feature in my perl code is there is some way to achieve this.

      I have just wasted 2 hours tracking down a bug that was caused by this flexibility and have had similar experiences in the past.

      In C++ and Java its disallowed/disallowable - presumably cos its considered bad form or more likely to be a typo than genuine code.

        I search CPAN for lexical and didn't find anything that might do the job. I'm sure it would be possible to write a source code filter for this (but you'll need perl 5.8.0).

        ----
        I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
        -- Schemer

        Note: All code is untested, unless otherwise stated

        Perl is not C++. Perl is not Java. Perl is more like C, and C allows this behavior:
        #include <stdio.h> int main() { int a = 1; { int a = 5; printf("inside a = %d\n", a); } printf("outside a = %d\n", a); }
        Personally, i think you might be wasting your time with this. I am not being mean, but maybe you should have coded this particular program in Java or C++. Use the right tool for the right job, don't change the tool because you may be using it for the wrong job. On another note, anytime i find myself wasting hours hunting down a bug, once i find it, i blame myself. ;)

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        
Re: Prohibiting redeclaration of lexicals in inner scope
by jdporter (Canon) on Mar 31, 2003 at 15:49 UTC
    Hmmm. I never run into this problem. Maybe it's because I give my variables good, meaningful names, not "a" or "var".

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

      Good for you.

      Dear oh dear ?!

Re: Prohibiting redeclaration of lexicals in inner scope
by diotalevi (Canon) on Mar 31, 2003 at 15:50 UTC

    I was going to answer this but it didn't answer the question. Perhaps some hacking about with PadWalker? Braver souls could implement a CHECK time function to walk all over the generated code and look for duplicated lexical names.

    Added I mean to say that while I don't know of any already implemented code, nothing that I'm aware of prevents someone (else) from creating it.

      I'm not up to that job unfortunately. Thx
Re: Prohibiting redeclaration of lexicals in inner scope
by nite_man (Deacon) on Mar 31, 2003 at 15:58 UTC
    In my mind, an easy way - before development your application to think over what names of variables you will use. Perl give us wild free hand but you should control an architecture of your application.
    --------> SV* sv_bless(SV* sv, HV* stash);
      Note that this took place within a single procedure and yep the variable names were nice and descriptive. The problem is that I didn't spot the extra 'my' lower down and so missed the reclaration.

      I cannot imagine a case where I personally would want to use this language feature and so would like to be warned about it whenever I do this in my code.

      Comments about variable naming etc do not help me.

      Thx

        "I cannot imagine a case where I personally would want to use this language feature ..."

        Well, for one, this feature is extremely useful when 'slurping' an entire file into a scalar. To do this, you must set $/ to an undefined value, but doing that could break client code. By only 'reseting' that variable inside a 'bare block', you guarantee that you will not break someone's client code that might use yours. In action, instead of using:

        my $data; while (<FILE>) { $data .= $_; }
        I can safely 'turn off' $/ temporarily via local:
        my $data = do {local $/ = undef;<FILE>}; # $/ contains it's original value (\n) now
        But ... i have been coding Perl for a good solid 4 years now. Your milleage may (and will) vary. I hope you decide to stick around, because we have lots of useful information for you. We just sometimes have to question why someone would even want to do something like this, that's all. :)

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        

        Not to make any assumptions, but how long is the sub, where did you originally declare the variable, how far away is its first use, and how far away the redeclaration? I'm just curious because I've never come across this problem and can't imagine it taking me hours to spot.

        I generally declare variables right when I use them the first time, and scope them tightly, trying to declare them in the innermost of the blocks they're used in. My code blocks are as short as I can keep them - a screenfull is long, more than two is under most circumstances too much. As a result, there's very rarely any occasion where a variable name is declared further than a screen from where it goes out of scope.

        For all intents and purposes these habits make it impossible to blunder in ways like this. Of course I may be way off mark, but it simply puzzles me that anyone would have this kind of trouble. My personal experience suggests it's just not possible to overlook duplicate declarations with habitual tight scoping and late declaration. YMMV of course.

        Makeshifts last the longest.

Re: Prohibiting redeclaration of lexicals in inner scope
by dragonchild (Archbishop) on Mar 31, 2003 at 16:14 UTC
    Apparently, this has not been a feature someone cared enough about to hack the core or write a module. JohnLon - if you really want this behavior, write the module (or the patch) and upload it to www.cpan.org. I'm sure that you aren't the only one who would be interested in this.

    If you do go ahead and write this - make it a lexically scoped directive, similar to strict and warnings.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Prohibiting redeclaration of lexicals in inner scope
by graff (Chancellor) on Mar 31, 2003 at 16:14 UTC
    I can't propose a detailed approach just now, but it would be along the lines of a perl script that would read perl code, look for declarations using "my", and normalize the text of these declarations so that you can look for duplicates easily. I have found B::Deparse to be useful in other cases where I wanted to look at perl code this way; it does an initial normalization of spacing around brackets and punctuation, making it a lot easier to look for things like subroutine definitions, variable declarations, etc.

    You'd want something that takes code a line at a time, and spits out all the "my ..." declarations, one per line of output, with the line number in the original code (which is scrupulously preserved by B::Deparse, I think -- but even if it isn't, just edit the output of B::Deparse, 'cuz it's probably more readable than the original when there's a difference).

    update: Here is an example using B::Deparse to tabulate sub defs and sub calls in perl code; might not be too big a stretch to make it focus on variable declarations instead.

      Thx but I'm only a novice and not really up to such a job.
      Was hoping someone had encountered this before.
      Bye JL
        I just hacked up a workable script to check for multiple uses of "my" with the same variable name -- find it here, under "cool uses for perl". It has its limitations, but perhaps it can be a useful crutch.
Re: Prohibiting redeclaration of lexicals in inner scope
by Abigail-II (Bishop) on Apr 04, 2003 at 14:41 UTC
    I get the impression that
    CC +w bad.c "c.c", line 7: Warning: i hides the same name in an outer scope.
    is a warning, not an error.

    One does have to question the merits of this warning though. What's easier to shut off this warning by removing the int from the inner declaration - on in Perl's case - by removing the my? Now you're warning free, but it's doubtful whether the quality of the code did improve.

    I've stumbled across this "warning" when compiling C as well. It always makes wanting to shout "Yes, of course, you moron compiler. That's why I use lexical variables, and not globals".

    Abigail

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://246950]
Approved by hardburn
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (9)
As of 2014-08-22 05:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (147 votes), past polls