CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Advanced:
use diagnostics - double standarts!?!?!

 



pozvanete
Novice

Mar 5, 2009, 7:13 AM

Post #1 of 9 (2592 views)
use diagnostics - double standarts!?!?! Can't Post

A piece of code (bellow) if in the whole script - diagnostics - gives me warning "Variable "%LINKS" will not stay shared".....

And this %LINKS is used ONLY in this module.

When I run this module in a separate file moduleonly.pl - diagnostic throws no warning. Any logic?!?!?



The whole warning is:

Variable "%LINKS" will not stay shared at C:\my_microweb\cgi-bin\firma\editor.pl line 431 (#1) (W closure) An inner (nested) named subroutine is referencing a lexical variable defined in an outer subroutine. When the inner subroutine is called, it will probably see the value of the outer subroutine's variable as it was before and during the *first* call to the outer subroutine; in this case, after the first call to the outer subroutine is complete, the inner and outer subroutines will no longer share a common value for the variable. In other words, the variable will no longer be shared. Furthermore, if the outer subroutine is anonymous and references a lexical variable outside itself, then the outer and inner subroutines will never share the given variable. This problem can usually be solved by making the inner subroutine anonymous, using the sub {} syntax. When inner anonymous subs that reference variables in outer subroutines are called or referenced, they are automatically rebound to the current values of such variables. Variable "%LINKS" will not stay shared at C:\my_microweb\cgi-bin\firma\editor.pl line 433 (#1)



The module is this

#!/usr/bin/perl -w

use lib "$ENV{'DOCUMENT_ROOT'}/cgi-bin/my_lib";

use MLDBM qw (SDBM_File);

use Data::Dumper;



use POSIX;

use Time::Local;

use CGI;

use strict ;

use diagnostics ;

print "Content-type:text/html\n\n";

print "<html><head><TITLE>MY WEBSITE INTERNAL URLs LIST</TITLE><BASEFONT FACE=VERDANA >";



my %LINKS;

&get_link('top_dir');

sub get_link{ my($dir)=@_; tie ( my %D, 'MLDBM', "dirs/$dir" , O_CREAT|O_RDWR, 0666) || die $!;foreach my $key (keys %D){ &enter_link($D{$key}->{'name'},$key,$dir); &get_link($key);} ; untie(%D)}





sub enter_link{

my($name,$num,$parent)=@_;

my $parent_url=''; my $parent_key=''; my $parent_name='';

foreach my $key (keys %LINKS){if($parent eq $LINKS{$key}->{'num'}){$parent_name=$LINKS{$key}->{'name'}; $parent_url=$LINKS{$key}->{'url'};$parent_key=$key;last;}}

my $new_link = "$parent_key$num"; my $url_num = length($new_link)/10+1; my $dots=''; if($url_num>2){$dots=':';}

my $sm =$LINKS{$new_link} ; $sm->{'num'}=$num;$sm->{'name'}="$parent_name$dots"; $sm->{'name'}.=$name;$sm->{'url'}=$parent_url;$sm->{'url'} .="\&$url_num=$num"; $LINKS{$new_link}= $sm;

}



my $link_options ='';

foreach my $key (sort keys %LINKS){ print "<LI> VALUE=?0=t&1=top_dir $LINKS{$key}->{'url'} >$LINKS{$key}->{'name'}"; }


1arryb
User

Mar 5, 2009, 8:51 AM

Post #2 of 9 (2585 views)
Re: [pozvanete] use diagnostics - double standarts!?!?! [In reply to] Can't Post

Hi posvanete,

How about removing "use MLDBM;" from your program? You aren't using it and the program checks fine without it.

UPDATE:

Ignore the above (must. drink. coffee.) Program compiles, but doesn't run.

Cheers,

Larry


(This post was edited by 1arryb on Mar 5, 2009, 9:01 AM)


pozvanete
Novice

Mar 5, 2009, 9:02 AM

Post #3 of 9 (2581 views)
Re: [1arryb] use diagnostics - double standarts!?!?! [In reply to] Can't Post

the rest of the program relies heavily on use MLDBM qw (SDBM_File). Can't remove it.



this is only one of the subs. the diagnostic suggests to convert one of the subs to anonimous - did try - but its the level of my ability :)

I will tolerate this warnings any way.



Thank you for your reply guys.


1arryb
User

Mar 5, 2009, 10:09 AM

Post #4 of 9 (2574 views)
Re: [pozvanete] use diagnostics - double standarts!?!?! [In reply to] Can't Post

Hi posvanete,

Back from Starbuck's and found a writeup on this warning at http://www.perl.com/pub/a/2002/05/07/mod_perl.html.

Given this writeup and the code you presented, the error should not be happening: You don't have nested subroutines in this code, only recursive calls to subroutines at the same lexical scope. In fact, this warning does not happen when I compile your code snippet on my machine, however it does when I compiled the sample program from the writeup.

The above, plus the fact that the warning is being triggered outside of your program (or, at least, the part you presented), tells me something is funny about how this script is invoked (in editor.pl) OR %LINKS (or a reference to it) is indeed used elsewhere.

What does line 431 of editor.pl look like?

Cheers,

Larry


(This post was edited by 1arryb on Mar 5, 2009, 10:18 AM)


FishMonger
Veteran / Moderator

Mar 5, 2009, 10:15 AM

Post #5 of 9 (2572 views)
Re: [pozvanete] use diagnostics - double standarts!?!?! [In reply to] Can't Post

Where is %LINKS being defined and populated?


1arryb
User

Mar 5, 2009, 10:22 AM

Post #6 of 9 (2568 views)
Re: [pozvanete] use diagnostics - double standarts!?!?! [In reply to] Can't Post

pozvanete,


Quote
I will tolerate this warnings any way.

NOOO!! This is a potentially serious runtime bug. If this code is called more than once in the same run, %LINKS will be invalid on the second and succeeding invocation. If that isn't your case, you can tolerate it, I suppose.

Larry


FishMonger
Veteran / Moderator

Mar 5, 2009, 10:56 AM

Post #7 of 9 (2563 views)
Re: [pozvanete] use diagnostics - double standarts!?!?! [In reply to] Can't Post

Part of the problem we have in helping you troubleshoot this is due to you only showing small pieces of your code that was most likely extracted from various sections of your script rather than an actual continuous block.

I now see the declaration of the %LINKS hash, but you don't show where or how you populate it.

Your code layout needs some rework to make it cleaner/easier to read, follow and troubleshoot.

For example, if you take your get_link() sub and add the proper amount of vertical and horizontal white space, you' see that it appears to be missing the closing brace, which would imply that enter_link() is its inner sub.


Code
sub get_link { 
my($dir)=@_;
tie ( my %D, 'MLDBM', "dirs/$dir" , O_CREAT|O_RDWR, 0666) || die $!;

foreach my $key (keys %D){
&enter_link($D{$key}->{'name'},$key,$dir);
&get_link($key);} ;
untie(%D)
}


<edit>Ahh, I see that it does have a closing brace that I missed, which goes to underscore the need to NOT string a bunch of statements into a single line.</edit>


(This post was edited by FishMonger on Mar 5, 2009, 11:11 AM)


pozvanete
Novice

Mar 5, 2009, 9:30 PM

Post #8 of 9 (2551 views)
Re: [FishMonger] use diagnostics - double standarts!?!?! [In reply to] Can't Post

This piece of code is a module &internal_links wich I open in a modal dialog window at the very begining of the script (bellow).

I hoped it would no interact with the rest of the code - but alas.

Sorry about the way the code is written. I usually crunch codes in one line , after its ready. (maybe bad practice, but help me be organised as a whole) . this code I did try my best to UNcrunch, :), The rest of the code is inreadable one lines.

BTW - is there any new software to compile perl scripts. Years ago I was testing a perl2exe - but was not pleased with the results?



#!/usr/bin/perl -w
use lib "$ENV{'DOCUMENT_ROOT'}/cgi-bin/my_lib";

use MLDBM qw (SDBM_File);
use Data::Dumper;use POSIX;
use Time::Local;
use CGI;
use strict ;

use diagnostics ;

my $q = new CGI

if($q->param('action')){ if($q->param('action') eq "internal_links"){ &internal_links;exit;}} ;


FishMonger
Veteran / Moderator

Mar 6, 2009, 6:47 AM

Post #9 of 9 (2542 views)
Re: [pozvanete] use diagnostics - double standarts!?!?! [In reply to] Can't Post

None of the code you've posted so far is a module. To be a module, it needs to create a new namespace (symbol table) and that is done via a package statement.

perldoc -f package
perldoc perlmod


Quote
The rest of the code is inreadable one lines.

That should tell you that your prior statement should be altered to:
"I usually crunch codes in one line, after its ready, which I know is bad practice"

After "uncruncing" the enter_link() sub, I see that %LINKS is a tied hash just like %D in the get_link() sub, but you didn't show us how/where that was done. Could it be that the my %LINKS statement that you did show us is interfering with the tied hash code?


Quote
BTW - is there any new software to compile perl scripts. Years ago I was testing a perl2exe - but was not pleased with the results?

It's been a long time since I've used perl2exe and I don't recall having problems with it, but I know it has had many improvements and might be worth giving it another try.

You can also take a look at PAR and related modules. I recently used it (meaning pp) and was pleased with the results.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives