experchange > perl

Mike Small (07-04-19, 08:41 PM)
A co-worker was trying to take some of the elements from gmtime's return
value. He did something like the following:

$ perl -E'$,="\t";say gmtime[1..5]'
8 32 12 31 7 2999416 1 243 0

I suggested he try something like this instead...

$ perl -E'$,="\t";say ((gmtime)[1..5])'
36 18 4 6 119

.... and that was what he wanted, but it didn't matter because he
re-rewrote his code to use strftime, which we both thought was more
readable. But still, what are those numbers in the first example?
Neither of us can figure where they come from. The parens must be a
clue, but all I could think was gmtime was interpreted as an array
reference, but thinking that didn't get me anywhere that made sense to
me.
Uri Guttman (07-08-19, 06:10 AM)
On 7/4/19 2:41 PM, Mike Small wrote:
> A co-worker was trying to take some of the elements from gmtime's return
> value. He did something like the following:
> $ perl -E'$,="\t";say gmtime[1..5]'


that is calling gmtime with the argument of [1..5] which is an arrayref.
so the arg to gmtime is some large address number. it is then parsed as
the timestamp and broken out. garbage in, garbage out!
> 8 32 12 31 7 2999416 1 243 0
> I suggested he try something like this instead...
> $ perl -E'$,="\t";say ((gmtime)[1..5])'
> 36 18 4 6 119

here gmtime is called with no args as it is in parens. so it uses the
value of time() which is what he wanted.

> ... and that was what he wanted, but it didn't matter because he
> re-rewrote his code to use strftime, which we both thought was more
> readable. But still, what are those numbers in the first example?
> Neither of us can figure where they come from. The parens must be a
> clue, but all I could think was gmtime was interpreted as an array
> reference, but thinking that didn't get me anywhere that made sense to
> me.

it is an array ref. but it is used as the epoch time and it is wacky for
that.

uri
Mike Small (07-08-19, 10:00 PM)
Uri Guttman <uri> writes:

> On 7/4/19 2:41 PM, Mike Small wrote:
> that is calling gmtime with the argument of [1..5] which is an
> arrayref. so the arg to gmtime is some large address number. it is
> then parsed as the timestamp and broken out. garbage in, garbage out!


Thanks Uri! That makes perfect sense now that I see it explained.
Uri Guttman (07-08-19, 10:21 PM)
On 7/8/19 4:00 PM, Mike Small wrote:
> Uri Guttman <uri> writes:
> Thanks Uri! That makes perfect sense now that I see it explained.

that is one reason a rule i use is to always (mostly!) use () for the
args list to builtins. it eliminates funny arg parsing and also shows to
the reader there is a function call with no args. it would have caught
the error as:

    gmtime()[1..5]

should be a syntax error (didn't check).

also a better way to slice out gmtime is to assign it to an list of
scalars or an array slice (untested):

    (undef, @gmt_parts[1..5) ) = gmtime() ;

and you can pass the list from gmtime directly to strftime (in POSIX) to
get a formatted date.

and in scalar context, you get a formatted date too. slicing into gmtime
isn't needed that often.

all the notes above cover localtime as well. gmtime is the basis for
localtime and the only difference is dealing with the local timezone and
its offset from GMT (same as UTC).

remember, write your code as if the maintainer is a homicidal maniac who
knows where you live!!

uri
Similar Threads