This looks like a Perl bug

G

George Mpouras

# it should print string, string but it prints string number
# there is no explanation for this behavior

weird('2') for 1..2;

sub weird {
my $num = $_[0] eq '' ? 0 : $_[0] ^ $_[0] ? 0 : 1;
my $col = $_[0] - 1;
print $num ? "number\n" : "string\n"
}
 
D

Dr.Ruud

# it should print string, string but it prints string number
# there is no explanation for this behavior

weird('2') for 1..2;

sub weird {
my $num = $_[0] eq '' ? 0 : $_[0] ^ $_[0] ? 0 : 1;
my $col = $_[0] - 1; print $num ? "number\n" : "string\n"
}

Not a bug. The parameter '2' becomes numeric, because of the operations.

Just rewrite it to:

sub silly {
my ($p) = @_; # copy
my $num = ($p eq "") ? 0 : ($p ^ $p) ? 0 : 1;
my $col = $p - 1;
print $num ? "number\n" : "string\n";
}


But what are you trying to achieve?
 
R

Rainer Weikusat

Dr.Ruud said:
# it should print string, string but it prints string number
# there is no explanation for this behavior

weird('2') for 1..2;

sub weird {
my $num = $_[0] eq '' ? 0 : $_[0] ^ $_[0] ? 0 : 1;
my $col = $_[0] - 1; print $num ? "number\n" : "string\n"
}

Not a bug. The parameter '2' becomes numeric, because of the
operations.

This is not quite true. Same effect with somewhat less code:

------------
weird('2') for 1 .. 2;

sub weird {
my $num = $_[0] ^ $_[0] ? 0 : 1;
my $col = $_[0] - 1;
print $num ? "number\n" : "string\n"
}
------------

What happens here is that $_[0] ^ $_[0] returns a string whose value
is a single 0-byte during the first call. This is not a 'logical false
value', hence $num becomes 1. The $_[0] - 1 causes the scalar supplied
as first argument to weird to become IOK, that is, it acquires an IV
whose value is 2. The same scalar is used as argument to the second
weird call. Consequently, $_[0] ^ $_[0] becomes an integer operation
whose result is 0 which counts as false and $num becomes 1.

If this is not considered a bug, this kind of 'silent' runtime
modification of compile-time literals is at least very
counter-intuitive.
 
R

Rainer Weikusat

[...]
my $num = $_[0] ^ $_[0] ? 0 : 1;
my $col = $_[0] - 1;
print $num ? "number\n" : "string\n"
}
------------

What happens here is that $_[0] ^ $_[0] returns a string whose value
is a single 0-byte during the first call. This is not a 'logical false
value', hence $num becomes 1.

s/becomes 1/becomes 0/
 
G

George Mpouras

the same peace of code is called with exact the same conditions and doing
different things
 
G

George Mpouras

its a very big project , what you see here is a very small piece of code
that expose the strange behaviour .

we had a very big headache to find what was wrong and where .
 
J

Jürgen Exner

"George Mpouras"
the same peace of code

It would help if you would include what piece (I'm assuming you meant
piece and not peace) of code you are talking about.
is called with exact the same conditions

It would help if you would state what those conditions are.
and doing different things

It would help if you would state what those different things are.

Without those details your statement is about as useful as "This thingy
is made of that green whatever".

jue
 
R

Rainer Weikusat

"George Mpouras"
the same peace of code is called with exact the same conditions and
doing different things

It is not called 'with the exact same conditions': The '2' ends
up as an anonymous scalar initialized to the value of the
string literal and the state of this anonymous scalar is changed by
the routine.

NB: I do not claim that this is not a bug, especially considering that
there's apparently some special-case code to prevent undefined values
from becoming defined as side effect of using them as numbers.
 
G

George Mpouras

Ο "Rainer Weikusat" έγÏαψε στο μήνυμα

"George Mpouras"
the same peace of code is called with exact the same conditions and
doing different things


no you are not right. it is well defined subroutine with one argument.
 
J

Jürgen Exner

"George Mpouras"
all you need to know is the piece of code I provide . nothing else .

You must have forgotten to provide that piece of code?

<fullquote>
the same peace of code is called with exact the same conditions and
doing
different things
</fullquote>

jue
 
R

Rainer Weikusat

"George Mpouras"
Ο "Rainer Weikusat" έγÏαψε στο μήνυμα
"George Mpouras"

[Text restored]
no you are not right. it is well defined subroutine with one
argument.

---------
use Devel::peek;

weird('2') for 1 .. 2;

sub weird {
Dump($_[0]);

my $num = $_[0] ^ $_[0] ? 0 : 1;
my $col = $_[0] - 1;
print $num ? "number\n" : "string\n";

Dump($_[0]);
}
---------

This prints

SV = PV(0x604308) at 0x621180
REFCNT = 1
FLAGS = (PADTMP,POK,READONLY,pPOK)
PV = 0x62a6b0 "2"\0
CUR = 1
LEN = 8
string
SV = PVIV(0x616a70) at 0x621180
REFCNT = 1
FLAGS = (PADTMP,IOK,POK,READONLY,pIOK,pPOK)
IV = 2
PV = 0x62a6b0 "2"\0
CUR = 1
LEN = 8
SV = PVIV(0x616a70) at 0x621180
REFCNT = 1
FLAGS = (PADTMP,IOK,POK,READONLY,pIOK,pPOK)
IV = 2
PV = 0x62a6b0 "2"\0
CUR = 1
LEN = 8
number
SV = PVIV(0x616a70) at 0x621180
REFCNT = 1
FLAGS = (PADTMP,IOK,POK,READONLY,pIOK,pPOK)
IV = 2
PV = 0x62a6b0 "2"\0
CUR = 1
LEN = 8
 
G

George Mpouras

# one more time


weird('2') for 1..2;

sub weird {
my $num = $_[0] eq '' ? 0 : $_[0] ^ $_[0] ? 0 : 1;
my $col = $_[0] - 1;
print $num ? "number\n" : "string\n"
}
 
D

Dr.Ruud

its a very big project , what you see here is a very small piece of code
that expose the strange behaviour .

we had a very big headache to find what was wrong and where .

Then what made you make the bad choice to depend on something internal?

This is in the "Doctor, it hurts when I press here." category.
It is basic to Perl that a value can have several natures at the same
time. And that these are cached. (Not nice for COW though.)

You now learned that you can use a copy of the parameter. Project saved?

Of course it is better to just get rid of the number/string thing
completely. How hard is that really?
 
C

Charlton Wilbur

"GM" == George Mpouras
GM> its a very big project , what you see here is a very small piece
GM> of code that expose the strange behaviour .

GM> we had a very big headache to find what was wrong and where .

The wrong thing is that you are trying to determine whether something is
a string or a number with foolish hackish approaches.

Read perlfaq4, s.v. "How do I determine whether a scalar is a
number/whole/integer/float?" and be enlightened.

Charlton
 
R

Rainer Weikusat

Ben Morrow said:
You're making the same mistake as Dr.Ruud. I don't believe George was
trying to determine whether a scalar was a string or a number, he was
being bitten by the fact the bitops change their behaviour based on
that.

Dispatching an abstract 'method invocation' to a specific 'method
implementation' based on the type of (some of) the arguments isn't a
particularly outlandish idea. And George actually already wrote what
he considered to be 'a bug', namely, the fact that a side-effect free
operation performed on a literal value causes that to change its type
because perl implicitly creates a scalar representing this literal
value and re-uses that for the 2nd invocation of the 'weird'
subroutine.

In the given context, that's an ill-conceived 'optimization hack',
even more so because it modifes a 'read only' value and yet more so
because this operation has been special-cased for 'undefined' values
to prevent them from becoming defined values in this way.
 
C

Charlton Wilbur

BM> You're making the same mistake as Dr.Ruud. I don't believe
BM> George was trying to determine whether a scalar was a string or
BM> a number,

In the absence of George saying why he is writing opaque and convoluted
code, we are left to infer and commit the intentional fallacy.

Charlton
 
X

Xho Jingleheimerschmidt

BM> You're making the same mistake as Dr.Ruud. I don't believe
BM> George was trying to determine whether a scalar was a string or
BM> a number,

In the absence of George saying why he is writing opaque and convoluted
code, we are left to infer and commit the intentional fallacy.

There is no doubt as to why he is writing that code. It is because it
exhibits the behavior he believes to be a bug. He was pretty explicit
about that. Your refusal to understand the obvious makes me ponder your
intention, perhaps fallaciously.

Xho
 

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,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top