[32700] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 3964 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Jun 13 14:14:20 2013

Date: Thu, 13 Jun 2013 11:14:10 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Thu, 13 Jun 2013     Volume: 11 Number: 3964

Today's topics:
        Perl values interchangeability? <oneingray@gmail.com>
    Re: Perl values interchangeability? <peter@makholm.net>
    Re: Perl values interchangeability? <oneingray@gmail.com>
    Re: Perl values interchangeability? <ben@morrow.me.uk>
    Re: Perl values interchangeability? <oneingray@gmail.com>
        UNITCHECK and require <adrien.barreau@live.fr>
    Re: UNITCHECK and require <ben@morrow.me.uk>
    Re: UNITCHECK and require <ben@morrow.me.uk>
    Re: UNITCHECK and require <adrien.barreau@live.fr>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Thu, 13 Jun 2013 08:04:45 +0000
From: Ivan Shmakov <oneingray@gmail.com>
Subject: Perl values interchangeability?
Message-Id: <878v2eiggy.fsf@violet.siamics.net>

	Do I understand it correctly that no Perl program could discern
	$a from $b, as long as ($a eq $b && ref ($a) eq ref ($b)) holds?

	(In particular, isn't there a certain module which allows one to
	peek into the Perl value's internal representation, such as
	whether the value has the "number" and "string" parts?)

	The context is that I'm implementing a span to value mapping,
	and wonder if I could allow the code to optimize, say:

    $map->set ($a, $b,  $value);    # $a < $b < $c < $d
    $map->set ($c, $d,  $value);
    $map->set ($b, $c,  $value);

	so that $map will internally hold the same information as if a
	single ->set ($a, $d, $value) was performed.

	TIA.

-- 
FSF associate member #7257


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

Date: Thu, 13 Jun 2013 10:44:31 +0200
From: Peter Makholm <peter@makholm.net>
Subject: Re: Perl values interchangeability?
Message-Id: <87ip1i9z80.fsf@vps1.hacking.dk>

Ivan Shmakov <oneingray@gmail.com> writes:

> 	Do I understand it correctly that no Perl program could discern
> 	$a from $b, as long as ($a eq $b && ref ($a) eq ref ($b)) holds?

Some operators behave differently based on whether the value of a scalar
has been interpreted as a string. Mainly the bit-wise logical operators
and the smart-match operator


Some values have specifically different content of the string part and
the number part of the value. For example $!. The following code would
make your assumption false:

  close(42);
  $a = $!;
  $b = "Bad file descriptor";

If $a is later used into a integer context it would have the value 9,
while $b would have the value 0. You can make these special values your
self with Scalar::Util::dualvar().


Tied values and objects with their own stringification will of course
also break your test.

> 	(In particular, isn't there a certain module which allows one to
> 	peek into the Perl value's internal representation, such as
> 	whether the value has the "number" and "string" parts?)

Devel::Peek will let you dump the internal representation of a value.

> 	The context is that I'm implementing a span to value mapping,
> 	and wonder if I could allow the code to optimize, say:
>
>     $map->set ($a, $b,  $value);    # $a < $b < $c < $d
>     $map->set ($c, $d,  $value);
>     $map->set ($b, $c,  $value);

A sane API would only depend on the numerical value or the string value
for non-reference scalars. So I would ignore most of the above issues
unless the documentation for a API specifically mentions it.

//Makholm


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

Date: Thu, 13 Jun 2013 13:22:23 +0000
From: Ivan Shmakov <oneingray@gmail.com>
Subject: Re: Perl values interchangeability?
Message-Id: <87wqpygn74.fsf@violet.siamics.net>

>>>>> Peter Makholm <peter@makholm.net> writes:
>>>>> Ivan Shmakov <oneingray@gmail.com> writes:

 >> Do I understand it correctly that no Perl program could discern
 >> $a from $b, as long as ($a eq $b && ref ($a) eq ref ($b)) holds?

	(... Assuming both are defined ()...)

 > Some operators behave differently based on whether the value of a
 > scalar has been interpreted as a string.  Mainly the bit-wise logical
 > operators and the smart-match operator.

	AIUI, these behave differently depending on whether a value is
	the /result/ of a string or numeric operation, or is a constant.
	In particular:

    my $a = 42;         # $a is numeric
    my $b = $a . "";    # $a was /interpreted/ as a string, yet still a number
    my $c = $b + 0;     # $b was /interpreted/ as a number, yet still a string

 > Some values have specifically different content of the string part
 > and the number part of the value.  For example $!.  The following
 > code would make your assumption false:

 >   close(42); $a = $!; $b = "Bad file descriptor";

 > If $a is later used into a integer context it would have the value 9,
 > while $b would have the value 0.  You can make these special values
 > your self with Scalar::Util::dualvar ().

	Do I understand it correctly that both of the values could be
	checked explicitly, as in:

sub same_val {
    my ($a, $b) = @_;
    ## .
    return (defined ($a) && defined ($b)
            && ref ($a) eq "" && ref ($b) eq ""
            && $a eq $b
            && $a == $b);
}

 > Tied values and objects with their own stringification will of course
 > also break your test.

	And how do I check for these (and especially the tied values)?

	For instance, will the following test suffice for objects
	implemented as references?

use Scalar::Util qw (refaddr reftype);

sub same_ref {
    my ($a, $b) = @_;
    my ($x, $y) = (reftype ($a), reftype ($b));
    ## .
    return (defined ($x) && defined ($y)
            && $x eq $y
            && refaddr ($a) eq refaddr ($b));
}

[...]

 >> The context is that I'm implementing a span to value mapping, and
 >> wonder if I could allow the code to optimize, say:

 >> $map->set ($a, $b,  $value);        # $a < $b < $c < $d
 >> $map->set ($c, $d,  $value);
 >> $map->set ($b, $c,  $value);

 > A sane API would only depend on the numerical value or the string
 > value for non-reference scalars.  So I would ignore most of the above
 > issues unless the documentation for a API specifically mentions it.

	ACK, thanks.

	Alas, the intent is to make the resulting object sufficiently
	generic, and "hash-like," and it'd hardly be acceptable for a
	hash to preserve only the string or numerical value of, well,
	the value.  And, for instance, $a{"x"} = $!; preserves both:

my %a = ();
close (42);
$a{"x"} = $!;
print (join (", ", $a{"x"} + 0, $a{"x"} . ""), "\n");
## => 9, Bad file descriptor

	Thus, unless it'd be possible to prove that the values cannot be
	distinguished at all (if they satisfy the same_ref () predicate,
	for instance; or?), I'd have to keep all of them.

-- 
FSF associate member #7257


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

Date: Thu, 13 Jun 2013 16:51:30 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Perl values interchangeability?
Message-Id: <2d6p8a-u9b2.ln1@anubis.morrow.me.uk>


Quoth Ivan Shmakov <oneingray@gmail.com>:
> >>>>> Peter Makholm <peter@makholm.net> writes:
> >>>>> Ivan Shmakov <oneingray@gmail.com> writes:
> 
>  >> Do I understand it correctly that no Perl program could discern
>  >> $a from $b, as long as ($a eq $b && ref ($a) eq ref ($b)) holds?
> 
> 	(... Assuming both are defined ()...)
> 
>  > Some operators behave differently based on whether the value of a
>  > scalar has been interpreted as a string.  Mainly the bit-wise logical
>  > operators and the smart-match operator.

The bitwise operators were a bug. The smart-match operator has been
deprecated (or retroactively marked experimental, or something), mostly
because it makes the same mistake only more so.

> 	AIUI, these behave differently depending on whether a value is
> 	the /result/ of a string or numeric operation, or is a constant.
> 	In particular:
> 
>     my $a = 42;         # $a is numeric
>     my $b = $a . "";    # $a was /interpreted/ as a string, 
>                           yet still a number

As far as the bitwise ops are concerned, this is true. Internally $a is
now POK and IOK, and it just happens that for the bitwise ops IOK takes
precedence.

>     my $c = $b + 0;     # $b was /interpreted/ as a number, 
>                           yet still a string

Nope. $b is now also POK and IOK, so the bitwise ops will now treat it
as a number. (This is why it was a bug for them to make the string/
number distinction in the first place: Perl just doesn't preserve that
information.)

>  > Some values have specifically different content of the string part
>  > and the number part of the value.  For example $!.  The following
>  > code would make your assumption false:
> 
>  >   close(42); $a = $!; $b = "Bad file descriptor";
> 
>  > If $a is later used into a integer context it would have the value 9,
>  > while $b would have the value 0.  You can make these special values
>  > your self with Scalar::Util::dualvar ().
> 
> 	Do I understand it correctly that both of the values could be
> 	checked explicitly, as in:
> 
> sub same_val {
>     my ($a, $b) = @_;
>     ## .
>     return (defined ($a) && defined ($b)

All undefined values are equal, at the Perl level at least.

>             && ref ($a) eq "" && ref ($b) eq ""
>             && $a eq $b
>             && $a == $b);
> }

It's usual in Perl to treat the string value as 'canonical'. Objects or
values which have the same string value but are in some important way
'different' are basically breaking the rules. (The string value is what
Test::More::is tests, for instance.)

>  > Tied values and objects with their own stringification will of course
>  > also break your test.
> 
> 	And how do I check for these (and especially the tied values)?

For tied values, tied(). For overloaded objects, see the overload
documentation; however you've already rejected refs above, so you won't
see objects of any kind. There are other kinds of magic, but they're
rare and probably not worth worrying about.

> 	For instance, will the following test suffice for objects
> 	implemented as references?

Objects are always 'implemented as references' in Perl. (More
specifically, an object only behaves as an object when manipulated via a
reference. A 'bare' blessed value, obtained by dereferencing an object
ref, is not distinguishable from a plain value.)

> use Scalar::Util qw (refaddr reftype);
> 
> sub same_ref {
>     my ($a, $b) = @_;
>     my ($x, $y) = (reftype ($a), reftype ($b));
>     ## .
>     return (defined ($x) && defined ($y)
>             && $x eq $y
>             && refaddr ($a) eq refaddr ($b));
> }

Well, you've missed 'blessed', which is a pretty important
characteristic of an object...

Are you testing for 'object equivalence' or 'object identity'? If you're
testing for identity (are these the same object?) then refaddr is
necessary and sufficient. If you want some other form of equivalence,
use the relevant equivalence operator (eq or ==).

>  >> The context is that I'm implementing a span to value mapping, and
>  >> wonder if I could allow the code to optimize, say:
> 
>  >> $map->set ($a, $b,  $value);        # $a < $b < $c < $d
>  >> $map->set ($c, $d,  $value);
>  >> $map->set ($b, $c,  $value);

(I assume here that the values you are comparing are the '$value's in
each case? That is, given

    $map->set(0, 2, $a);
    $map->set(1, 3, $b);

you want to know if $a and $b are sufficiently 'equal' that you can
merge this into

    $map->set(0, 3, $a);

)

>  > A sane API would only depend on the numerical value or the string
>  > value for non-reference scalars.  So I would ignore most of the above
>  > issues unless the documentation for a API specifically mentions it.
> 
> 	ACK, thanks.
> 
> 	Alas, the intent is to make the resulting object sufficiently
> 	generic, and "hash-like," and it'd hardly be acceptable for a
> 	hash to preserve only the string or numerical value of, well,
> 	the value.  And, for instance, $a{"x"} = $!; preserves both:
> 
> my %a = ();
> close (42);
> $a{"x"} = $!;
> print (join (", ", $a{"x"} + 0, $a{"x"} . ""), "\n");
> ## => 9, Bad file descriptor
> 
> 	Thus, unless it'd be possible to prove that the values cannot be
> 	distinguished at all (if they satisfy the same_ref () predicate,
> 	for instance; or?), I'd have to keep all of them.

You can definitely merge the entries if

    ref($a) && ref($b) && refaddr($a) == refaddr($b)

since in that case they are both refs to the same referent. You
obviously can't merge them if one is a ref and the other isn't. For the
case of two non-refs, I would probably just compare them with 'eq' and
document that fact, but if you are worried about special cases probably
the simplest solution is to pass both values through Storable and
compare the results. If either value is tied you can't assume anything.

It would probably also be worth providing a user-specified 'merge'
function, so that the user can choose to allow merges more often (say,
if they have some class of objects with a non-obvious equivalence
relation).

Ben



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

Date: Thu, 13 Jun 2013 17:48:48 +0000
From: Ivan Shmakov <oneingray@gmail.com>
Subject: Re: Perl values interchangeability?
Message-Id: <87ehc5hpfj.fsf@violet.siamics.net>

>>>>> Ben Morrow <ben@morrow.me.uk> writes:
>>>>> Quoth Ivan Shmakov <oneingray@gmail.com>:
>>>>> Peter Makholm <peter@makholm.net> writes:

[...]

 >> (... Assuming both are defined ()...)

[...]

 >> my $c = $b + 0; # $b was /interpreted/ as a number, yet still a string

 > Nope.  $b is now also POK and IOK, so the bitwise ops will now treat
 > it as a number.  (This is why it was a bug for them to make the
 > string/number distinction in the first place: Perl just doesn't
 > preserve that information.)

	!  That was, for the lack of a better word, unexpected.

[...]

 >> Do I understand it correctly that both of the values could be
 >> checked explicitly, as in:

 >> sub same_val {
 >>     my ($a, $b) = @_;
 >>     ## .
 >>     return (defined ($a) && defined ($b)

 > All undefined values are equal,

	That's a guard against otherwise possible ("" eq undef) below,
	used instead of a proper conditional branch for the sake of
	simplicity.  (Please note that my original predicate was
	assuming defined () values, too.)

 > at the Perl level at least.

	... Moreover, an application may choose to use undef as an
	"unknown" value.  Thus: same ($a, undef) == same (undef, $b) ==
	same (undef, undef) == undef.  (Although it's not the behavior
	I'm interested in in this case.)

 >>             && ref ($a) eq "" && ref ($b) eq ""
 >>             && $a eq $b
 >>             && $a == $b);
 >> }

 > It's usual in Perl to treat the string value as 'canonical'.  Objects
 > or values which have the same string value but are in some important
 > way 'different' are basically breaking the rules.  (The string value
 > is what Test::More::is tests, for instance.)

	ACK, thanks.

 >>> Tied values and objects with their own stringification will of
 >>> course also break your test.

 >> And how do I check for these (and especially the tied values)?

 > For tied values, tied ().  For overloaded objects, see the overload
 > documentation; however you've already rejected refs above, so you
 > won't see objects of any kind.

	To clarify it, the predicate above was intended to be used for
	the "simple" values only, and be combined with same_ref () below
	if necessary.

 > There are other kinds of magic, but they're rare and probably not
 > worth worrying about.

	Curiously, is $! one of them?  FWIW, while Scalar::Util(3)
	states that it's a tied scalar, tied ($!) is undef.

[...]

 > Objects are always 'implemented as references' in Perl.  (More
 > specifically, an object only behaves as an object when manipulated
 > via a reference.  A 'bare' blessed value, obtained by dereferencing
 > an object ref, is not distinguishable from a plain value.)

[...]

 > Are you testing for 'object equivalence' or 'object identity'?

	The latter.

 > If you're testing for identity (are these the same object?) then
 > refaddr is necessary and sufficient.

	... I wonder if it's codified somewhere in the documentation?
	I understand that on a J. von Neumann architecture there's
	hardly any other sensible way to implement Perl's objects and
	references, yet...

 > If you want some other form of equivalence, use the relevant
 > equivalence operator (eq or ==).

	ACK, thanks.

[...]

 >>> $map->set ($a, $b, $value);        # $a < $b < $c < $d
 >>> $map->set ($c, $d, $value);
 >>> $map->set ($b, $c, $value);

 > (I assume here that the values you are comparing are the '$value's in
 > each case?  That is, given

 >     $map->set(0, 2, $a); $map->set(1, 3, $b);

 > you want to know if $a and $b are sufficiently 'equal' that you can
 > merge this into

 >     $map->set(0, 3, $a);

 > )

	Yes.

[...]

 >> Thus, unless it'd be possible to prove that the values cannot be
 >> distinguished at all (if they satisfy the same_ref () predicate, for
 >> instance; or?), I'd have to keep all of them.

 > You can definitely merge the entries if

 >     ref($a) && ref($b) && refaddr($a) == refaddr($b)

 > since in that case they are both refs to the same referent.  You
 > obviously can't merge them if one is a ref and the other isn't.

 > For the case of two non-refs, I would probably just compare them with
 > 'eq' and document that fact, but if you are worried about special
 > cases probably the simplest solution is to pass both values through
 > Storable and compare the results.  If either value is tied you can't
 > assume anything.

 > It would probably also be worth providing a user-specified 'merge'
 > function, so that the user can choose to allow merges more often
 > (say, if they have some class of objects with a non-obvious
 > equivalence relation).

	I guess that allowing for a user-specified equality / merge
	predicate (to be used unless the values are refaddr-equal) will
	be sufficient for this one.  Thanks!

-- 
FSF associate member #7257


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

Date: Wed, 12 Jun 2013 13:16:32 +0200
From: Adrien BARREAU <adrien.barreau@live.fr>
Subject: UNITCHECK and require
Message-Id: <kp9l1g$mpc$1@dont-email.me>

Hi all.

I just found a way to kill my Perl and I don't find anything about that.
Here it is:

=====
$ perl --version

This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
(with 61 registered patches, see perl -V for more detail)


$ cat death.pm
package death;
UNITCHECK { require stuff; }
1;

$ cat stuff.pm
package stuff;
1;

$ perl -e 'use death; print "ok\n";'
$ perl -e 'require death; print "ok\n";'
Segmentation fault
=====

Well, perhaps trying to require something in a UNITCHECK is not a good idea.
But still, segfault...

That's strange that the "use" version does not actually display anything 
at all, although that seems to be quite random.

Does anybody have any piece of information about that?


Adrien.


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

Date: Wed, 12 Jun 2013 16:24:20 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: UNITCHECK and require
Message-Id: <4egm8a-jon1.ln1@anubis.morrow.me.uk>


Quoth Adrien BARREAU <adrien.barreau@live.fr>:
> Hi all.
> 
> I just found a way to kill my Perl and I don't find anything about that.
> Here it is:
> 
> =====
> $ perl --version
> 
> This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
> (with 61 registered patches, see perl -V for more detail)
> 
> 
> $ cat death.pm
> package death;
> UNITCHECK { require stuff; }
> 1;
> 
> $ cat stuff.pm
> package stuff;
> 1;
> 
> $ perl -e 'use death; print "ok\n";'
> $ perl -e 'require death; print "ok\n";'
> Segmentation fault
> =====
> 
> Well, perhaps trying to require something in a UNITCHECK is not a good idea.
> But still, segfault...

Definitely a bug, but it appears to be fixed in 5.14. (5.12 still has
the bug.) Interestingly, in a threaded perl you get 'death.pm did not
return a true value' instead.

Ben



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

Date: Wed, 12 Jun 2013 17:09:49 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: UNITCHECK and require
Message-Id: <d3jm8a-p6p1.ln1@anubis.morrow.me.uk>


Quoth Ben Morrow <ben@morrow.me.uk>:
> Quoth Adrien BARREAU <adrien.barreau@live.fr>:
> > 
> > $ cat death.pm
> > package death;
> > UNITCHECK { require stuff; }
> > 1;
> > 
> > $ cat stuff.pm
> > package stuff;
> > 1;
> > 
> > $ perl -e 'use death; print "ok\n";'
> > $ perl -e 'require death; print "ok\n";'
> > Segmentation fault
> > =====
> > 
> > Well, perhaps trying to require something in a UNITCHECK is not a good idea.
> > But still, segfault...
> 
> Definitely a bug, but it appears to be fixed in 5.14.

For the record, I suspect this is the same bug as
https://rt.perl.org/rt3/Public/Bug/Display.html?id=70614 . It doesn't
look the same until you remember that 'require' is really just a
variation of string-eval.

Ben



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

Date: Wed, 12 Jun 2013 18:47:36 +0200
From: Adrien BARREAU <adrien.barreau@live.fr>
Subject: Re: UNITCHECK and require
Message-Id: <kpa8e8$4vi$1@dont-email.me>

On 06/12/2013 06:09 PM, Ben Morrow wrote:

>
> For the record, I suspect this is the same bug as
> https://rt.perl.org/rt3/Public/Bug/Display.html?id=70614 . It doesn't
> look the same until you remember that 'require' is really just a
> variation of string-eval.
>
> Ben
>

I can reproduce something strange behaviours like that:

=====
$ cat death.pm
package death;
UNITCHECK { eval '' }
1;

$ perl -e 'require death; print "ok\n"'
$
# ---

$ cat death.pm
package death;
UNITCHECK { eval {} }
1;

$ perl -e 'require death; print "ok\n"'
ok
=====

No segfault, but nothing either with an eval-string.
Strange...

Adrien.


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

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:

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

Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests. 

#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 3964
***************************************


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