"anonymous" variable in Perl?

R

Ronald Fischer

Consider a call to, say, localtime, where I only need the current month:

my ($a, $b, $c, $d, $month) = localtime time,

Here I had to invent names ($a...$d) for the first four fields. Is it possible
in Perl to have kind of an "anonymous" variable as a placeholder for those
fields, similar to the '_' variable in Prolog?

I darkly remember to have read about such a feature introduced with Perl 5.6,
but I can't find out how to do it.

Ronald
 
R

Richard Gration

Consider a call to, say, localtime, where I only need the current month:

my ($a, $b, $c, $d, $month) = localtime time,

Here I had to invent names ($a...$d) for the first four fields. Is it possible
in Perl to have kind of an "anonymous" variable as a placeholder for those
fields, similar to the '_' variable in Prolog?

I darkly remember to have read about such a feature introduced with Perl 5.6,
but I can't find out how to do it.

Ronald

You can use undef as an lvalue, as in:

my $month;
(undef,undef,undef,undef,$month) = localtime time;

However, in this case you might be better off using:

my $month = (localtime)[4];

which indexes directly in to the return from localtime, which is a list.
And which defaults to using time() as the time too.

Rich
 
K

KKramsch

In said:
Consider a call to, say, localtime, where I only need the current month:
my ($a, $b, $c, $d, $month) = localtime time,
Here I had to invent names ($a...$d) for the first four fields. Is it possible
in Perl to have kind of an "anonymous" variable as a placeholder for those
fields, similar to the '_' variable in Prolog?

You could use

(undef, undef, undef, undef, my $month) = localtime;

What I usually do in such cases is something like this

my $month = (localtime)[4];

Karl
 
J

J. Romano

Richard Gration said:
You can use undef as an lvalue, as in:

my $month;
(undef,undef,undef,undef,$month) = localtime time;


Just so you know, you can combine the above two lines to one that
looks like:

my (undef, undef, undef, undef, $month) = localtime time;

or even (as has already been pointed out by another poster):

(undef, undef, undef, undef, my $month) = localtime time;

I prefer the first line over the second because I find it's more
readable.

I wouldn't normally think that an "undef" would be allowed in a
variable declaration list, but fortunately Perl is smart enough to
realize that "undef" in a variable declaration list should be ignored.
(As a result, "undef" occasionally makes a great placeholder.)

Just thought you might want to know.

-- Jean-Luc
 
J

Juha Laiho

KKramsch said:
Consider a call to, say, localtime, where I only need the current month:
my ($a, $b, $c, $d, $month) = localtime time,

What I usually do in such cases is something like this

my $month = (localtime)[4];

.... and if more than one of the return values is needed, it's equally simple:

my ($day,$month) = (localtime)[3,4];
 
V

Veli-Pekka Tätilä

Juha said:
... and if more than one of the return values is needed, it's equally
simple:
my ($day,$month) = (localtime)[3,4];
Nice, an array slice. Couldn't you also use the range operator to say get
the values two to five with [2 ..5 ]?

One quick question, though. Is there an elegant way of getting the time
components in a hash? It would be easier to memorize if the components had
human-readable names. I think the indeces are mostly arbitrary apart from
going from smaller units to larger which somewhat helps.
 
A

Anno Siegel

Veli-Pekka Tätilä said:
Juha Laiho wrote:
... and if more than one of the return values is needed, it's equally
simple:
my ($day,$month) = (localtime)[3,4];
Nice, an array slice. Couldn't you also use the range operator to say get
the values two to five with [2 ..5 ]?

One quick question, though. Is there an elegant way of getting the time
components in a hash? It would be easier to memorize if the components had
human-readable names. I think the indeces are mostly arbitrary apart from
going from smaller units to larger which somewhat helps.

You can do it manually,

my %t;
@t{ qw( sec, min, hour, mday, mon, year, wday, yday, isdst)} = localtime;
my ( $day, $month) = @t{ qw( mday mon)};

but that's probably not what you mean by elegant. The non-standard
module Time::piece (available from CPAN) does it for you. It overrides
localtime() and gmtime() so that they return objects which support
appropriate methods.

use Time::piece;
my $t = localtime;
( $day, $month) = ($t->mday, $t->mon);

Note that Time::piece returns the month (and year) in conventional
counting (from 1) whereas localtime() counts from 0.

Anno
 
V

Veli-Pekka Tätilä

Anno Siegel wrote:
You can do it manually, <<snip>
but that's probably not what you mean by elegant.
Well, no. Having to memorize the ordre at the point of using the function
sort of negates my point. Because if you memorize the order, it is just
easier to deal with a list and comment appropriately.
module Time::piece (available from CPAN) does it for you. It overrides
localtime() and gmtime() so that they return objects
Ah, that's the ticket. I'm not sure if I'll change to this interface
full-time but nice to know someone has already done the hard work, as usual
in Perl.
Note that Time::piece returns the month (and year) in conventional
counting (from 1)
Actually, I find this more intuitive.
 
I

Ilmari Karonen

Veli-Pekka Tätilä said:
Juha said:
... and if more than one of the return values is needed, it's equally
simple:
my ($day,$month) = (localtime)[3,4];
Nice, an array slice. Couldn't you also use the range operator to say get
the values two to five with [2 ..5 ]?

One quick question, though. Is there an elegant way of getting the time
components in a hash? It would be easier to memorize if the components had
human-readable names. I think the indeces are mostly arbitrary apart from
going from smaller units to larger which somewhat helps.

For one more way to do it, see the examples section in "perldoc constant".

--
Ilmari Karonen
To reply by e-mail, please replace ".invalid" with ".net" in address.

"My father used to claim that he heard god on numerous occasions. He
would ask god questions and keep a record of the answers, and at the end
of the year he would do a chi-square analysis to find out whether god had
been right more often than chance would lead one to expect." -- Pat Bowne
 
P

Peter Scott

The non-standard
module Time::piece (available from CPAN) does it for you. It overrides
localtime() and gmtime() so that they return objects which support
appropriate methods.

use Time::piece;
my $t = localtime;
( $day, $month) = ($t->mday, $t->mon);

Unnecessary to use a non-standard module:

% perl
use Time::localtime;
my ($day, $month) = (localtime->mday, localtime->mon);
print "$day $month\n";
^D
8 7
 
A

Anno Siegel

Peter Scott said:
Unnecessary to use a non-standard module:

% perl
use Time::localtime;
my ($day, $month) = (localtime->mday, localtime->mon);
print "$day $month\n";
^D
8 7

Ah, good to know there's an alternative. I like the functionality of
Time::piece, but not the implementation.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top