[30999] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 2244 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Mon Mar 2 16:09:45 2009

Date: Mon, 2 Mar 2009 13:09:11 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Mon, 2 Mar 2009     Volume: 11 Number: 2244

Today's topics:
        help with GD module <aa@aa.com>
    Re: help with GD module <zentara@highstream.net>
    Re: help with GD module <glex_no-spam@qwest-spam-no.invalid>
        list context of cgi param problem in hash initializatio <michaelgang@gmail.com>
    Re: list context of cgi param problem in hash initializ <noreply@gunnar.cc>
    Re: list context of cgi param problem in hash initializ <ben@morrow.me.uk>
    Re: list context of cgi param problem in hash initializ (Tim McDaniel)
    Re: list context of cgi param problem in hash initializ <jimsgibson@gmail.com>
    Re: Net::SSH2 scp_put not working! <schaitan@gmail.com>
    Re: Net::SSH2 scp_put not working! <schaitan@gmail.com>
    Re: Net::SSH2 scp_put not working! <ben@morrow.me.uk>
        perl dates: a notify alert window <ericcire@gmail.com>
    Re: perl dates: a notify alert window <cartercc@gmail.com>
    Re: perl dates: a notify alert window <jurgenex@hotmail.com>
    Re: perl dates: a notify alert window <1usa@llenroc.ude.invalid>
    Re: perl dates: a notify alert window <jurgenex@hotmail.com>
    Re: perl dates: a notify alert window <cartercc@gmail.com>
        variables that won't stay shared <cartercc@gmail.com>
    Re: variables that won't stay shared <ben@morrow.me.uk>
        wxperl <aa@aa.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Mon, 2 Mar 2009 13:12:02 +0100
From: "abcd" <aa@aa.com>
Subject: help with GD module
Message-Id: <gogiej$mra$1@news.metronet.hr>

use GD::Graph::bars;
my @data = (
['frogs','fish','toads','rodents'],
[ 8, 3, 1, 2],
);
my $chart = GD::Graph::bars->new(700,500);
$chart->set(title => 'Ostrich diet');
$chart->set_title_font('arialbd', 24);
$chart->set_x_axis_font('arial', 16);
$chart->set_y_axis_font('arial', 16);
my $gd_object = $chart->plot(\@data);


but don't work, only open a cmd windown a nothing else!

how I can create a window with graphics?




------------------------------

Date: Mon, 02 Mar 2009 07:32:16 -0500
From: zentara <zentara@highstream.net>
Subject: Re: help with GD module
Message-Id: <faknq41n9v126bn6uuhql59rhibm823ffk@4ax.com>

On Mon, 2 Mar 2009 13:12:02 +0100, "abcd" <aa@aa.com> wrote:

>use GD::Graph::bars;
>my @data = (
>['frogs','fish','toads','rodents'],
>[ 8, 3, 1, 2],
>);
>my $chart = GD::Graph::bars->new(700,500);
>$chart->set(title => 'Ostrich diet');
>$chart->set_title_font('arialbd', 24);
>$chart->set_x_axis_font('arial', 16);
>$chart->set_y_axis_font('arial', 16);
>my $gd_object = $chart->plot(\@data);
>
>
>but don't work, only open a cmd windown a nothing else!
>
>how I can create a window with graphics?
>

You can use Image Magick's display utility, or even easier, put the
output in a Tk window.

Example: (attention: Tk likes it's photo's base64 encoded )

#!/usr/bin/perl  -w
use GD;
use Tk;
use Tk::PNG;
use MIME::Base64;

my $main = new MainWindow;
my $photo_obj = $main->Photo(-data => get_graph() );

my $display = $main->Label(-image => $photo_obj,
			  )->pack(-fill=>'both', -expand=>1); 

$main->Button(-text => 'exit',
              -command => sub{exit}
              )->pack();


MainLoop;

sub get_graph{
my $gd = GD::Image->new(400,300);
my $white  = $gd->colorAllocate(255, 255, 255);
my $black  = $gd->colorAllocate(  0,   0,   0);
my $red    = $gd->colorAllocate(255,   0,   0);
my $green  = $gd->colorAllocate(  0, 255,   0);
my $blue   = $gd->colorAllocate(  0,   0, 255);
my $yellow = $gd->colorAllocate(255, 255,   0);

$gd->filledRectangle(0, 129, 199, 169, $blue);

my $poly = GD::Polygon->new();
$poly->addPt(199, 149);
$poly->addPt(399,  74);
$poly->addPt(324, 149);
$poly->addPt(399, 224);
$gd->filledPolygon($poly, $yellow);
$gd->polygon      ($poly, $black);
$gd->arc(199, 149, 250, 250, 0, 360, $red);

# Tk likes it's images base64encoded
return  encode_base64( $gd->png() );
}

__END__ 


zentara

-- 
I'm not really a human, but I play one on earth.
http://www.zentara.net/~zentaran/My_Petition_to_the_Great_Cosmic_Conciousness.html 


------------------------------

Date: Mon, 02 Mar 2009 10:42:14 -0600
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: help with GD module
Message-Id: <49ac0c67$0$33219$815e3792@news.qwest.net>

abcd wrote:
> use GD::Graph::bars;
> my @data = (
> ['frogs','fish','toads','rodents'],
> [ 8, 3, 1, 2],
> );
> my $chart = GD::Graph::bars->new(700,500);
> $chart->set(title => 'Ostrich diet');
> $chart->set_title_font('arialbd', 24);
> $chart->set_x_axis_font('arial', 16);
> $chart->set_y_axis_font('arial', 16);
> my $gd_object = $chart->plot(\@data);
> 
> 
> but don't work, only open a cmd windown a nothing else!

Why would you expect it to display the image?

> 
> how I can create a window with graphics?

Use the Tk module or save it as a file and use a browser or some
other application, such as a browser, to display it.


------------------------------

Date: Mon, 2 Mar 2009 03:28:22 -0800 (PST)
From: david <michaelgang@gmail.com>
Subject: list context of cgi param problem in hash initialization
Message-Id: <1ef871d4-f687-4f98-a17f-f1c99dfbeda1@v38g2000yqb.googlegroups.com>

Hi all,

I have a script with the following

%a = (foo=>$cgi->param('foo'), boo=>$cgi->param('boo'))

I have a problem if foo was not defined then the cgi thinks that i
want list context and returns an empty array.
then the order of the hash is broken and for $a{foo} i get boo.

one way is to write
%a = (foo=>scalar $cgi->param('foo'), boo=>scalar $cgi->param('boo'))

but this is not elegant.

Has someone a more elegant solution for this problem ?

Thanks in advance,
David


------------------------------

Date: Mon, 02 Mar 2009 13:03:51 +0100
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: list context of cgi param problem in hash initialization
Message-Id: <71205nFiuu8uU1@mid.individual.net>

david wrote:
> I have a script with the following
> 
> %a = (foo=>$cgi->param('foo'), boo=>$cgi->param('boo'))
> 
> I have a problem if foo was not defined then the cgi thinks that i
> want list context and returns an empty array.
> then the order of the hash is broken and for $a{foo} i get boo.
> 
> one way is to write
> %a = (foo=>scalar $cgi->param('foo'), boo=>scalar $cgi->param('boo'))
> 
> but this is not elegant.
> 
> Has someone a more elegant solution for this problem ?

Other way (but not more elegant IMO):

     %a = (
         foo => $cgi->param('foo') || undef,
         boo => $cgi->param('boo') || undef,
     );

or maybe:

     %a = $cgi->Vars;

But in the latter case, the key 'foo' does not exist. Only you can tell 
whether that matters.

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl


------------------------------

Date: Mon, 2 Mar 2009 12:47:03 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: list context of cgi param problem in hash initialization
Message-Id: <731t76-q83.ln1@osiris.mauzo.dyndns.org>


Quoth david <michaelgang@gmail.com>:
> 
> I have a script with the following
> 
> %a = (foo=>$cgi->param('foo'), boo=>$cgi->param('boo'))
> 
> I have a problem if foo was not defined then the cgi thinks that i
> want list context and returns an empty array.
> then the order of the hash is broken and for $a{foo} i get boo.
> 
> one way is to write
> %a = (foo=>scalar $cgi->param('foo'), boo=>scalar $cgi->param('boo'))
> 
> but this is not elegant.
> 
> Has someone a more elegant solution for this problem ?

I would simply factor it out as

    my %a = map { ($_, scalar $cgi->param($_)) } qw/foo boo/;

An alternative would be

    my %a;
    $a{$_} = $cgi->param($_) for qw/foo boo/;

where the individual assignments give ->param scalar context.

Ben



------------------------------

Date: Mon, 2 Mar 2009 16:56:22 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: list context of cgi param problem in hash initialization
Message-Id: <goh33l$qmn$1@reader1.panix.com>

In article
<1ef871d4-f687-4f98-a17f-f1c99dfbeda1@v38g2000yqb.googlegroups.com>,
david  <michaelgang@gmail.com> wrote:
>I have a script with the following
>
>%a = (foo=>$cgi->param('foo'), boo=>$cgi->param('boo'))
>
>I have a problem if foo was not defined then the cgi thinks that i
>want list context and returns an empty array.
>then the order of the hash is broken and for $a{foo} i get boo.
>
>one way is to write
>%a = (foo=>scalar $cgi->param('foo'), boo=>scalar $cgi->param('boo'))
>
>but this is not elegant.
>
>Has someone a more elegant solution for this problem ?

Um, am I missing something about why

    $a{foo} = $cgi->param('foo');
    $a{boo} = $cgi->param('boo');

doesn't work?  Or, if the cgi param and the hash index are always
required to be equal, and if you have a list of many of them,

    $a{$_} = $cgi->param($_) for qw(boo coo goo loo moo poo roux too woo zoo);

?

-- 
Tim McDaniel, tmcd@panix.com


------------------------------

Date: Mon, 02 Mar 2009 09:53:49 -0800
From: Jim Gibson <jimsgibson@gmail.com>
Subject: Re: list context of cgi param problem in hash initialization
Message-Id: <020320090953491462%jimsgibson@gmail.com>

In article
<1ef871d4-f687-4f98-a17f-f1c99dfbeda1@v38g2000yqb.googlegroups.com>,
david <michaelgang@gmail.com> wrote:

> Hi all,
> 
> I have a script with the following
> 
> %a = (foo=>$cgi->param('foo'), boo=>$cgi->param('boo'))
> 
> I have a problem if foo was not defined then the cgi thinks that i
> want list context and returns an empty array.
> then the order of the hash is broken and for $a{foo} i get boo.
> 
> one way is to write
> %a = (foo=>scalar $cgi->param('foo'), boo=>scalar $cgi->param('boo'))
> 
> but this is not elegant.
> 
> Has someone a more elegant solution for this problem ?

If you want the input parameters as a hash, you can call the Vars()
method, which returns a reference to a hash. You could then use a hash
slice to copy the parameters you want to another hash, if needed.

-- 
Jim Gibson


------------------------------

Date: Mon, 2 Mar 2009 05:12:32 -0800 (PST)
From: Krishna Chaitanya <schaitan@gmail.com>
Subject: Re: Net::SSH2 scp_put not working!
Message-Id: <ff768d1c-cd04-4dcf-9eee-a79a45ac3c28@v5g2000prm.googlegroups.com>

Is there a case I'm missing where blocking(0) leads to successful
execution and read of a command through $channel->shell() and setting
blocking(1) makes it hang indefinitely?

I've understood polling and related topics, thanks to all your inputs,
but it defeats me completely why setting blocking(1) would hang any
command forever. What am I missing here conceptually?

Many thanks, everyone, for your edifying words...


------------------------------

Date: Mon, 2 Mar 2009 05:35:28 -0800 (PST)
From: Krishna Chaitanya <schaitan@gmail.com>
Subject: Re: Net::SSH2 scp_put not working!
Message-Id: <a2f4b99d-16dc-4e31-a0f7-4e6ccb59f971@d36g2000prf.googlegroups.com>

Also, can anyone please take this program and execute at their end and
tell me if they succeeded in getting the command output?

#!/usr/bin/perl

use warnings;
use strict;

use Net::SSH2;

my $ssh2 = Net::SSH2->new();

$ssh2->connect(<an IP you can connect to>) or die;

if ($ssh2->auth_password(<username>,<password>)) {
        print "Authorization successful\n";
        my $chan2 = $ssh2->channel();
        $chan2->shell();
        $chan2->blocking(1);
        print $chan2 "uname -a\n";
        print "LINE : $_" while <$chan2>;
        $chan2->close();
        $ssh2->scp_put(<Path-to-any-file-to-be-scp-ed>) or warn "Could
not scp the file <filename> ";
} else {
        print "Authorization failure\n";
}

Thanks again!


------------------------------

Date: Mon, 2 Mar 2009 15:44:22 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Net::SSH2 scp_put not working!
Message-Id: <mfbt76-hn7.ln1@osiris.mauzo.dyndns.org>


Quoth Krishna Chaitanya <schaitan@gmail.com>:
> Also, can anyone please take this program and execute at their end and
> tell me if they succeeded in getting the command output?
> 
> #!/usr/bin/perl
> 
> use warnings;
> use strict;
> 
> use Net::SSH2;
> 
> my $ssh2 = Net::SSH2->new();
> 
> $ssh2->connect(<an IP you can connect to>) or die;
> 
> if ($ssh2->auth_password(<username>,<password>)) {

The first problem I had was that my server doesn't allow 'password'
auth, it requires 'keyboard' auth. The libssh2 documentation says this
is quite common, so you may want to watch for it.

>         print "Authorization successful\n";
>         my $chan2 = $ssh2->channel();
>         $chan2->shell();
>         $chan2->blocking(1);
>         print $chan2 "uname -a\n";
>         print "LINE : $_" while <$chan2>;

The second problem is here. It turns out that the ->READLINE and ->GETC
methods on Net::SSH2::Channel require the session to be in non-blocking
mode, but they don't set it themselves, and they don't handle timeouts
properly. I would consider this a fairly serious bug in Net::SSH2. 

If your connection is fast enough that you can always guarantee to get a
new character within 250ms of the last, you can set ->blocking(0) around
all <> calls and it will stop hanging. If a character is late, however,
you will not only get an undef returned from <> when you shouldn't but
you will lose the whole of the line that's been read so far. I would
recommend dropping the tied filehandle interface and using ->read and
->write instead, however that will make finding newlines considerably
harder.

Also, you have a logic error here I hadn't noticed before. Had the <>
been working properly, it would not have returned undef until the other
end set end-of-file. Since the other end is a shell which is waiting for
another command, that was never going to happen.

Ben



------------------------------

Date: Mon, 2 Mar 2009 11:41:45 -0800 (PST)
From: Eric <ericcire@gmail.com>
Subject: perl dates: a notify alert window
Message-Id: <7dd6096e-4103-43b3-b413-e125900f9d82@l39g2000yqn.googlegroups.com>


I'm having a little difficulty with this one. I want to have a notify
script "not" send messages during a weekend "quiet window" from Friday
17:00 through Sunday 17:00. Sounds simple enough on the surface. I
just need an "okToSend()"  function to return a True (1) if the
current date and time are not within that blackout window.

But .... how do you do this?
If the current epoch timestamp is $now = time; How do I determine if
it's within this blackout window? Not so simple. I've tried
calculating the start of week Monday, and then adding enough seconds
to determine Friday 17:00 and the same for Sunday 17:00 and then
seeing if the current timestamp is between these two numbers .... but
my code is not very elegant and this just feels like the wrong
approach.

Any suggestions?


Thanks,
Eric


------------------------------

Date: Mon, 2 Mar 2009 11:58:39 -0800 (PST)
From: cartercc <cartercc@gmail.com>
Subject: Re: perl dates: a notify alert window
Message-Id: <3515c352-f474-4da8-86cc-4a95c1d4081e@w9g2000yqa.googlegroups.com>

Eric wrote:
> I'm having a little difficulty with this one. I want to have a notify
> script "not" send messages during a weekend "quiet window" from Friday
> 17:00 through Sunday 17:00. Sounds simple enough on the surface. I
> just need an "okToSend()"  function to return a True (1) if the
> current date and time are not within that blackout window.

localtime() returns both the hour and the weekday, like this:

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime
(time);
print qq(day is $wday and hour is $hour\n);
my $quiet_window = 1;
#default
if ($wday == 5 and $hour > 17) { $quiet_window = 0; }    #Friday night
elsif ($wday == 6)  { $quiet_window = 0; }
#Saturday
elsif ($wday == 0 and $hour < 17) { $quiet_window = 0; } #Sunday
morning
else { $quiet_window = 01 }
#default again


------------------------------

Date: Mon, 02 Mar 2009 11:59:29 -0800
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: perl dates: a notify alert window
Message-Id: <lgeoq4t0k281mt1kt287iv44ljpu12pon7@4ax.com>

Eric <ericcire@gmail.com> wrote:
>just need an "okToSend()"  function to return a True (1) if the
>current date and time are not within that blackout window.
>
>But .... how do you do this?

Take a look at Date::Calc. It has numerous functions to determine things
like the current day of the week (is it Fri/Sat/Sun?) and the current
time (if is after 17:00 (for Friday) or before 17:00 (for Sunday)).

jue


------------------------------

Date: Mon, 02 Mar 2009 20:20:39 GMT
From: "A. Sinan Unur" <1usa@llenroc.ude.invalid>
Subject: Re: perl dates: a notify alert window
Message-Id: <Xns9BC29C159906Basu1cornelledu@127.0.0.1>

Eric <ericcire@gmail.com> wrote in news:7dd6096e-4103-43b3-b413-
e125900f9d82@l39g2000yqn.googlegroups.com:

> 
> I'm having a little difficulty with this one. I want to have a notify
> script "not" send messages during a weekend "quiet window" from Friday
> 17:00 through Sunday 17:00. Sounds simple enough on the surface. I
> just need an "okToSend()"  function to return a True (1) if the
> current date and time are not within that blackout window.

#!/usr/bin/perl

use strict;
use warnings;

sub is_blackout {
    my ($hour, $wday) = localtime[2,6];

    return ( $wday == 5 && $hour > 17 )
        or ( $wday == 6 )
        or ( $wday == 0 && $hour < 17 )
    ;
}

print is_blackout() ? "Yes" : "No", "\n";




-- 
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/


------------------------------

Date: Mon, 02 Mar 2009 12:25:51 -0800
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: perl dates: a notify alert window
Message-Id: <rhfoq4l491acq11v46n1ftdvs8mlvnlkmn@4ax.com>

cartercc <cartercc@gmail.com> wrote:
>Eric wrote:
>> I'm having a little difficulty with this one. I want to have a notify
>> script "not" send messages during a weekend "quiet window" from Friday
>> 17:00 through Sunday 17:00. Sounds simple enough on the surface. I
>> just need an "okToSend()"  function to return a True (1) if the
>> current date and time are not within that blackout window.
>
>localtime() returns both the hour and the weekday, like this:
>
>my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime
>(time);
>print qq(day is $wday and hour is $hour\n);
>my $quiet_window = 1;
>#default
>if ($wday == 5 and $hour > 17) { $quiet_window = 0; }    #Friday night
>elsif ($wday == 6)  { $quiet_window = 0; }
>#Saturday
>elsif ($wday == 0 and $hour < 17) { $quiet_window = 0; } #Sunday
>morning
>else { $quiet_window = 01 }
>#default again

Please don't take this personal, but this is actually a very nice
example code, where people don't trust boolean algebra.
To me 

sub quiet_window {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 		
	localtime(time);
return ( ($wday == 5 and $hour > 17) #Friday
	or ($wday == 6)		#Saturday
	or ($wday == 0 and $hour < 17) #Sunday
}

is much easier to write, to read, and to understand than that cascading
elsif chain.

The query for localtime could also be rewritten as 
my (undef, undef, $hour, undef, undef, undef, $wday, undef, undef) =
localtime(time); 
because those two values are all you want. 

Or even better use an array slice:
	my ($hour, $wday) = localtime(time)[2,6];
to extract exactly those elements you are interested in.

jue


------------------------------

Date: Mon, 2 Mar 2009 12:34:32 -0800 (PST)
From: cartercc <cartercc@gmail.com>
Subject: Re: perl dates: a notify alert window
Message-Id: <8eec2ca2-cffd-4eed-984d-d82830cbd2cf@t3g2000yqa.googlegroups.com>

On Mar 2, 3:25=A0pm, J=FCrgen Exner <jurge...@hotmail.com> wrote:
> Please don't take this personal, but this is actually a very nice
> example code, where people don't trust boolean algebra.
> To me
>
> sub quiet_window {
> my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =3D =A0 =A0 =A0 =
=A0 =A0 =A0 =A0
> =A0 =A0 =A0 =A0 localtime(time);
> return ( ($wday =3D=3D 5 and $hour > 17) #Friday
> =A0 =A0 =A0 =A0 or ($wday =3D=3D 6) =A0 =A0 =A0 =A0 #Saturday
> =A0 =A0 =A0 =A0 or ($wday =3D=3D 0 and $hour < 17) #Sunday
>
> }
>
> is much easier to write, to read, and to understand than that cascading
> elsif chain.

No offense taken at all. I didn't take the time to make this efficient
in any way or to dress it up -- I only wanted to convey the idea that
localtime() returns the values you need. Also, it's not a matter of
not trusting Boolean algebra, but of clarifying the logic. When I
first dashed this off, I had all the logic in a single set of
parentheses, but I changed it to make it clear that one had to test
BOTH the day and the hour. Obviously, there's more than one way to do
it.

> Or even better use an array slice:
> =A0 =A0 =A0 =A0 my ($hour, $wday) =3D localtime(time)[2,6];
> to extract exactly those elements you are interested in.

 ... at the risk of confusing someone who doesn't know what an array
slice is, as I myself at one time didn't. The differences between
@var, $var, and $var[0] are confusing enough without throwing in @var
[0]. ;-)

CC


------------------------------

Date: Mon, 2 Mar 2009 11:14:36 -0800 (PST)
From: cartercc <cartercc@gmail.com>
Subject: variables that won't stay shared
Message-Id: <e8a98e57-103c-4052-9600-de35d13515b1@q11g2000yqh.googlegroups.com>

I have a big glob of data that I'm extracting from a database using
selectall_hashref(). I'm using the primary key to manipulate the data
but I have to print out the data sorted by date, not the primary key.
Here's the relevant portion of the code:

sub output
(
 ...
 foreach my $key (sort bydate keys %{$calendarhash})
   {
 ...
      print qq($calendarhash->{$key}{'calid'} $calendarhash->{$key}
{'event'} $calendarhash->{$key}{'eventdate'}   $calendarhash->{$key}
{'addby'}  $calendarhash->{$key}{'adddate'} \n);
 ...
  }
   #----------bydate------------------
      sub bydate
      {
         my  $date_a = $calendarhash->{$a}{'eventdate'};
         my $date_b = $calendarhash->{$b}{'eventdate'};
         return $date_a cmp $date_b;
      }
   #---------------------------------
}

Here's the error message using diagnostics:

$ perl -cw console
Variable "$calendarhash" will not stay shared at CONSOLE.pm line 191
(#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.

[Mon Mar  2 13:58:38 2009] CONSOLE.pm: Variable "$calendarhash" will
not stay shared at CONSOLE.pm line 191.
Variable "$calendarhash" will not stay shared at MUPD.pm line 209 (#1)
[Mon Mar  2 13:58:38 2009] MUPD.pm: Variable "$calendarhash" will not
stay shared at MUPD.pm line 209.
console syntax OK
$

I want to place the bydate() function WITHIN the lexical scope of the
display function, and can't understand why Perl complains. (Actually,
I can understand why Perl complains, I just can't understand why it
SHOULD complain.)

Is this error message significant? If so, should I remove the bydate()
function from the scope of the display function? I don't care to use
an anonymous function as I feel that it needlessly obscures the code,
and I want to keep the sorting function in the main function for the
same reason.

Thanks, CC.


------------------------------

Date: Mon, 2 Mar 2009 20:23:21 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: variables that won't stay shared
Message-Id: <pqrt76-iq9.ln1@osiris.mauzo.dyndns.org>


Quoth cartercc <cartercc@gmail.com>:
> I have a big glob of data that I'm extracting from a database using
> selectall_hashref(). I'm using the primary key to manipulate the data
> but I have to print out the data sorted by date, not the primary key.
> Here's the relevant portion of the code:
<snip>
> 
> Here's the error message using diagnostics:
> 
> $ perl -cw console
> Variable "$calendarhash" will not stay shared at CONSOLE.pm line 191
> (#1)
<snip>
> 
> I want to place the bydate() function WITHIN the lexical scope of the
> display function, and can't understand why Perl complains. (Actually,
> I can understand why Perl complains, I just can't understand why it
> SHOULD complain.)

You should never place a named sub anywhere that will execute more than
once, whether this is inside another sub or in a loop at the top level.
If you find yourself doing this, you should probably be using an anon
sub instead, since named subs are not closures in Perl 5.

> Is this error message significant?

Yes, it's absolutely significant. A cutdown version of your code with
enough program round it to test it might look like:

    #!/usr/bin/perl -l

    sub output {
        my $calendarhash = { @_ };
        
        foreach my $key (sort bydate keys %{$calendarhash}) {
            print $key;
        }

        sub bydate {
            my $date_a = $calendarhash->{$a};
            my $date_b = $calendarhash->{$b};
            return $date_a cmp $date_b;
        }
    }

    print "FIRST TIME:";
    output a => 1, b => 2;

    print "SECOND TIME:";
    output a => 2, b => 1;

and the output would be

    FIRST TIME:
    a
    b
    SECOND TIME:
    a
    b

Notice how even though the keys have opposite values the second time,
they still get sorted in the original order. This is because the second
time (and every time thereafter) the bydate sub will still be using the
value of $calendarhash from the first time. This is an unfortunate
limitation in Perl, and the workaround is to use an anon sub instead.

> If so, should I remove the bydate() function from the scope of the
> display function? I don't care to use an anonymous function as I feel
> that it needlessly obscures the code, and I want to keep the sorting
> function in the main function for the same reason.

I don't quite understand your objection here. Using an anon sub is the
only answer. Moving the bydate sub outside the output sub won't compile:
$calendarhash is scoped to the output sub (I presume) so you'll get
'strict' errors. Making $calendarhash global is clearly a bad idea.

What exactly do you think is wrong with

    foreach my $key (
        sort { 
            $calendarhash->{$a}{...} cmp $calendarhash->{$b}{...} 
        } keys %{$calendarhash}
    ) {

I realise it's a little longwinded, but that's mostly because of your
over-long variable name (it's partly because of the somewhat unfortunate
calling convention of perl's sort). If your sub is so long that a name
like $cal is ambiguous, you need to break it up.

Of course, you could always use something like

    sub sortkv (&\%) {
        my ($sub, $hash) = @_;

        sort {
            local $_ = $hash->{$a};
            my $xa = $sub->();
            $_ = $hash->{$b};
            my $xb = $sub->();
            $xa cmp $xb;
        } keys %$hash;
    }

which would let you write

    for my $key (sortkv { $_->{...} } %$calendarhash) {

but you probably think that's too obscure as well. Oddly there doesn't
seem to be a Sort::Util or Hash::MoreUtils on CPAN that this might be
in...

Ben



------------------------------

Date: Mon, 2 Mar 2009 15:44:59 +0100
From: "abcd" <aa@aa.com>
Subject: wxperl
Message-Id: <gogrdc$t9h$1@news.metronet.hr>

suport wxperl all function which include in wx for c++? 




------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc.  For subscription or unsubscription requests, send
#the single line:
#
#	subscribe perl-users
#or:
#	unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.  

NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice. 

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.

#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V11 Issue 2244
***************************************


home help back first fref pref prev next nref lref last post