Mailing List Archive

1 2  View All
Re: pre-pre-RFC: "unbless" [ In reply to ]
* Nicholas Clark <nick@ccl4.org> [2021-07-06 12:57:31 +0000]:

> On Tue, Jul 06, 2021 at 10:03:56AM +0000, Nicholas Clark wrote:
>
> > Also, JSON can't serialise all things that Perl objects can contain.
> > Most blatantly, references to scalars:
>
> > There isn't actually anything "blessed" here - I think that this object in
> > the error message is part of the internal implementation.
>
> No, the problem is that the tide went out in my coffee mug.
>
> perl -MCpanel::JSON::XS -lwe 'my $j = Cpanel::JSON::XS->new(); print $j->encode(\$a)'
> cannot encode reference to scalar 'SCALAR(0x556b542a3918)' unless the scalar is 0 or 1 at -e line 1.
>
> The rest still holds:
>
> > So "unbless" doesn't just solve the problem of TO_JSON. There will still
> > be objects that need to be thought about.
> >
> > And as (I think) Chris Prather observed, if one "unblesses" an object, that
> > likely will break any object that was relying on DESTROY.
> >
> >
> > "unbless" might be a reasonable idea, but it doesn't safely solve the
> > general problem of serialisation of data structures containing objects.
> > Likely trying to use it to would actually make things worse.

So what I've gathered from most replies is:

1. "unbless" is a reasonable idea
2. some don't like my reason why it's reasonable for my use cases

Can you tell me why you think it's reasonable? And rather than try
to disprove my personal reasons for thinking its also reasonable,
can we focus on why it's generally reasonable - since consensus
seems to be that it is, in fact, a positive suggestion? This might
help us generate even more "reasonable" ideas, and help us tune
into what sort of reasons are used to determine this for more
healthy and productive discussions.

We even might be able to learn as a group how to collaborate, or
maybe I'll just learn how to be a better contributor.

FWIW, I am not trying to solve the general issue of "serialization".
Sometimes I just want to "unbless" something that I have previously
blessed. Nothing fancy, no recursion (we don't expect 'bless' to
act recursively).

Also, I very much appreciate all the positive comments and Paul's
willingness to add this to Scalar::Util.

Cheers,
Brett

>
> Nicholas Clark

--
--
oodler@cpan.org
oodler577@sdf-eu.org
SDF-EU Public Access UNIX System - http://sdfeu.org
irc.perl.org #openmp #pdl #native
Re: pre-pre-RFC: "unbless" [ In reply to ]
(1) unbless is a reasonable idea on general principles: anything you
can set you should be able to unset.

(2) Scalar::Util::unbless sounds like an excellent solution

(3) Alternately, I might suggest some new second argument to bless
that tells it to peform an unbless.

my $ref = bless( $obj, __NULLCLASS__ );

(It's unfortunate that an undef or an empty string means something
already-- And while I can't imagine wanting to use that feature
myself, I don't want to discuss whether anyone might be using it-- we
have no way to know how people use perl, and I'd like to stop going
around on that.)


On 7/6/21, Oodler 577 via perl5-porters <perl5-porters@perl.org> wrote:
> * Nicholas Clark <nick@ccl4.org> [2021-07-06 12:57:31 +0000]:
>
>> On Tue, Jul 06, 2021 at 10:03:56AM +0000, Nicholas Clark wrote:
>>
>> > Also, JSON can't serialise all things that Perl objects can contain.
>> > Most blatantly, references to scalars:
>>
>> > There isn't actually anything "blessed" here - I think that this object
>> > in
>> > the error message is part of the internal implementation.
>>
>> No, the problem is that the tide went out in my coffee mug.
>>
>> perl -MCpanel::JSON::XS -lwe 'my $j = Cpanel::JSON::XS->new(); print
>> $j->encode(\$a)'
>> cannot encode reference to scalar 'SCALAR(0x556b542a3918)' unless the
>> scalar is 0 or 1 at -e line 1.
>>
>> The rest still holds:
>>
>> > So "unbless" doesn't just solve the problem of TO_JSON. There will
>> > still
>> > be objects that need to be thought about.
>> >
>> > And as (I think) Chris Prather observed, if one "unblesses" an object,
>> > that
>> > likely will break any object that was relying on DESTROY.
>> >
>> >
>> > "unbless" might be a reasonable idea, but it doesn't safely solve the
>> > general problem of serialisation of data structures containing objects.
>> > Likely trying to use it to would actually make things worse.
>
> So what I've gathered from most replies is:
>
> 1. "unbless" is a reasonable idea
> 2. some don't like my reason why it's reasonable for my use cases
>
> Can you tell me why you think it's reasonable? And rather than try
> to disprove my personal reasons for thinking its also reasonable,
> can we focus on why it's generally reasonable - since consensus
> seems to be that it is, in fact, a positive suggestion? This might
> help us generate even more "reasonable" ideas, and help us tune
> into what sort of reasons are used to determine this for more
> healthy and productive discussions.
>
> We even might be able to learn as a group how to collaborate, or
> maybe I'll just learn how to be a better contributor.
>
> FWIW, I am not trying to solve the general issue of "serialization".
> Sometimes I just want to "unbless" something that I have previously
> blessed. Nothing fancy, no recursion (we don't expect 'bless' to
> act recursively).
>
> Also, I very much appreciate all the positive comments and Paul's
> willingness to add this to Scalar::Util.
>
> Cheers,
> Brett
>
>>
>> Nicholas Clark
>
> --
> --
> oodler@cpan.org
> oodler577@sdf-eu.org
> SDF-EU Public Access UNIX System - http://sdfeu.org
> irc.perl.org #openmp #pdl #native
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an
> email to doom+unsubscribe@kzsu.stanford.edu.
>
>
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Tue, Jul 06, 2021 at 07:03:19PM -0700, Joseph Brenner wrote:
> (1) unbless is a reasonable idea on general principles: anything you
> can set you should be able to unset.

I agree on general principles, but disagree here.

Consider we're "unblessing" an object that is implemented as
a hash. We know it's a hash and will be accessing it via
hash syntax to serialize or dump it.

Any code to do this will probably be where the class is
defined, the implementation is known, and it will
appropriate to explicity say bless $obj, 'HASH' when
serializing and perhaps afterwards, bless $obj, $class to
restore the object behavior.

We can reasonably expect the author to know it's going from
a blessed hash reference to a plain hash and back.

Unless there a strong use for "unbless" outside the class
definition I would consider it a burden, at least for core
perl.

regards,

Joel Roth

> (2) Scalar::Util::unbless sounds like an excellent solution
>
> (3) Alternately, I might suggest some new second argument to bless
> that tells it to peform an unbless.
>
> my $ref = bless( $obj, __NULLCLASS__ );
>
> (It's unfortunate that an undef or an empty string means something
> already-- And while I can't imagine wanting to use that feature
> myself, I don't want to discuss whether anyone might be using it-- we
> have no way to know how people use perl, and I'd like to stop going
> around on that.)
>
>
> On 7/6/21, Oodler 577 via perl5-porters <perl5-porters@perl.org> wrote:
> > * Nicholas Clark <nick@ccl4.org> [2021-07-06 12:57:31 +0000]:
> >
> >> On Tue, Jul 06, 2021 at 10:03:56AM +0000, Nicholas Clark wrote:
> >>
> >> > Also, JSON can't serialise all things that Perl objects can contain.
> >> > Most blatantly, references to scalars:
> >>
> >> > There isn't actually anything "blessed" here - I think that this object
> >> > in
> >> > the error message is part of the internal implementation.
> >>
> >> No, the problem is that the tide went out in my coffee mug.
> >>
> >> perl -MCpanel::JSON::XS -lwe 'my $j = Cpanel::JSON::XS->new(); print
> >> $j->encode(\$a)'
> >> cannot encode reference to scalar 'SCALAR(0x556b542a3918)' unless the
> >> scalar is 0 or 1 at -e line 1.
> >>
> >> The rest still holds:
> >>
> >> > So "unbless" doesn't just solve the problem of TO_JSON. There will
> >> > still
> >> > be objects that need to be thought about.
> >> >
> >> > And as (I think) Chris Prather observed, if one "unblesses" an object,
> >> > that
> >> > likely will break any object that was relying on DESTROY.
> >> >
> >> >
> >> > "unbless" might be a reasonable idea, but it doesn't safely solve the
> >> > general problem of serialisation of data structures containing objects.
> >> > Likely trying to use it to would actually make things worse.
> >
> > So what I've gathered from most replies is:
> >
> > 1. "unbless" is a reasonable idea
> > 2. some don't like my reason why it's reasonable for my use cases
> >
> > Can you tell me why you think it's reasonable? And rather than try
> > to disprove my personal reasons for thinking its also reasonable,
> > can we focus on why it's generally reasonable - since consensus
> > seems to be that it is, in fact, a positive suggestion? This might
> > help us generate even more "reasonable" ideas, and help us tune
> > into what sort of reasons are used to determine this for more
> > healthy and productive discussions.
> >
> > We even might be able to learn as a group how to collaborate, or
> > maybe I'll just learn how to be a better contributor.
> >
> > FWIW, I am not trying to solve the general issue of "serialization".
> > Sometimes I just want to "unbless" something that I have previously
> > blessed. Nothing fancy, no recursion (we don't expect 'bless' to
> > act recursively).
> >
> > Also, I very much appreciate all the positive comments and Paul's
> > willingness to add this to Scalar::Util.
> >
> > Cheers,
> > Brett
> >
> >>
> >> Nicholas Clark
> >
> > --
> > --
> > oodler@cpan.org
> > oodler577@sdf-eu.org
> > SDF-EU Public Access UNIX System - http://sdfeu.org
> > irc.perl.org #openmp #pdl #native
> >
> > --
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to doom+unsubscribe@kzsu.stanford.edu.
> >
> >

--
Joel Roth
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Tue, 6 Jul 2021 at 22:43, Oodler 577 via perl5-porters <
perl5-porters@perl.org> wrote:

> * Nicholas Clark <nick@ccl4.org> [2021-07-06 12:57:31 +0000]:
>
> > On Tue, Jul 06, 2021 at 10:03:56AM +0000, Nicholas Clark wrote:
> >
> > > Also, JSON can't serialise all things that Perl objects can contain.
> > > Most blatantly, references to scalars:
> >
> > > There isn't actually anything "blessed" here - I think that this
> object in
> > > the error message is part of the internal implementation.
> >
> > No, the problem is that the tide went out in my coffee mug.
> >
> > perl -MCpanel::JSON::XS -lwe 'my $j = Cpanel::JSON::XS->new(); print
> $j->encode(\$a)'
> > cannot encode reference to scalar 'SCALAR(0x556b542a3918)' unless the
> scalar is 0 or 1 at -e line 1.
> >
> > The rest still holds:
> >
> > > So "unbless" doesn't just solve the problem of TO_JSON. There will
> still
> > > be objects that need to be thought about.
> > >
> > > And as (I think) Chris Prather observed, if one "unblesses" an object,
> that
> > > likely will break any object that was relying on DESTROY.
> > >
> > >
> > > "unbless" might be a reasonable idea, but it doesn't safely solve the
> > > general problem of serialisation of data structures containing objects.
> > > Likely trying to use it to would actually make things worse.
>
> So what I've gathered from most replies is:
>
> 1. "unbless" is a reasonable idea
> 2. some don't like my reason why it's reasonable for my use cases
>

"we can apply a package tag to a reference, so we should be able to remove
the tag as well" is quite a reasonable request, yes. As such, I'm all in
favour of adding this to Scalar::Util (and/or Ref::Util).

However, there are various assumptions that might not be a problem for your
cases, but could lead to unhappy surprises for an unwary developer -
whether they're looking for a generic serialisation option or something
else:

- objects are blessed hashrefs

There's work being done on an alternative OO system (Corinna) which very
likely _won't_ be based on blessed hashrefs. The Object::Pad
proof-of-concept implementation would give you an arrayref, for example.
There are also other modules such as Struct::Dumb which have key/value
attributes but don't store as hashrefs.

- all the object content should be exposed as part of the serialisation

What if there's cached data or references to other objects?

- we want a destructive operation

Since every other reference to this object is affected, this can lead to
some very unfortunate action-at-a-distance. As an example, say you had this
as the last step in a webapp REST handler as a shortcut to JSON
serialisation, then later wanted to add caching... your cached object would
lose all its methods, potentially breaking the next request.

- we don't want recursion

If this only removes the package tag on the target object, it's not going
to help much on its own for nested data structures such as trees. Also,
depending on how you manually recurse through a tree object hierarchy, you
might start unblessing things that were needed, and losing the ability to
iterate through other parts of the tree...

Personally I see this as a useful tool in a few rare situations, but a bad
option for both of your original use-cases (and previous discussion from
other people has covered the reasons in a lot more detail).
Re: pre-pre-RFC: "unbless" [ In reply to ]
Seems to me that these are documented:

bless $thingy;
bless $thingy, '';

but

bless $thingy, undef;

is not.

Phasing out undocumented behavior like this after a deprecation cycle is pretty consistent with what has happened in the past.

--
Aaron Priven, aaron@priven.com, www.priven.com/aaron
Re: pre-pre-RFC: "unbless" [ In reply to ]
Aaron Priven <aaron@priven.com> wrote:
> Seems to me that these are documented:
>
> bless $thingy;
> bless $thingy, '';
>
> but
>
> bless $thingy, undef;
>
> is not.

perlfunc has:

> This function tells the thingy referenced by REF
> that it is now an object in the CLASSNAME
> package. If CLASSNAME is an empty string, it is
> interpreted as referring to the main package. If
> CLASSNAME is omitted, the current package is used.

I think if you "omit" the CLASSNAME that's the same as
passing it an undef.

Distinguishing between these two cases in perl would
seem strange to me:

bless $obj;
bless $obj, undef;
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Wed, Jul 7, 2021 at 2:21 PM Joseph Brenner <doomvox@gmail.com> wrote:

> Aaron Priven <aaron@priven.com> wrote:
> > Seems to me that these are documented:
> >
> > bless $thingy;
> > bless $thingy, '';
> >
> > but
> >
> > bless $thingy, undef;
> >
> > is not.
>
> perlfunc has:
>
> > This function tells the thingy referenced by REF
> > that it is now an object in the CLASSNAME
> > package. If CLASSNAME is an empty string, it is
> > interpreted as referring to the main package. If
> > CLASSNAME is omitted, the current package is used.
>
> I think if you "omit" the CLASSNAME that's the same as
> passing it an undef.
>
> Distinguishing between these two cases in perl would
> seem strange to me:
>
> bless $obj;
> bless $obj, undef;
>

This is a solid point and would lead me to vote against making undef
special in bless directly.

-Dan
Re: pre-pre-RFC: "unbless" [ In reply to ]
{package AAA;
use Data::Dump qw(dump);
my $a = {};
bless $a, undef;
say STDERR dump($a);
}

# Use of *uninitialized* value in bless
# Explicit blessing to '' (assuming package main)
# bless({}, "main")

On Wed, Jul 7, 2021 at 7:28 PM Dan Book <grinnz@gmail.com> wrote:

> On Wed, Jul 7, 2021 at 2:21 PM Joseph Brenner <doomvox@gmail.com> wrote:
>
>> Aaron Priven <aaron@priven.com> wrote:
>> > Seems to me that these are documented:
>> >
>> > bless $thingy;
>> > bless $thingy, '';
>> >
>> > but
>> >
>> > bless $thingy, undef;
>> >
>> > is not.
>>
>> perlfunc has:
>>
>> > This function tells the thingy referenced by REF
>> > that it is now an object in the CLASSNAME
>> > package. If CLASSNAME is an empty string, it is
>> > interpreted as referring to the main package. If
>> > CLASSNAME is omitted, the current package is used.
>>
>> I think if you "omit" the CLASSNAME that's the same as
>> passing it an undef.
>>
>> Distinguishing between these two cases in perl would
>> seem strange to me:
>>
>> bless $obj;
>> bless $obj, undef;
>>
>
> This is a solid point and would lead me to vote against making undef
> special in bless directly.
>
> -Dan
>
Re: pre-pre-RFC: "unbless" [ In reply to ]
Philip R Brenan <philiprbrenan@gmail.com> wrote:
>> Joseph Brenner <doomvox@gmail.com> wrote:

>>> perlfunc has:
>>>
>>> > This function tells the thingy referenced by REF
>>> > that it is now an object in the CLASSNAME
>>> > package. If CLASSNAME is an empty string, it is
>>> > interpreted as referring to the main package. If
>>> > CLASSNAME is omitted, the current package is used.
>>>
>>> I think if you "omit" the CLASSNAME that's the same as
>>> passing it an undef.

> {package AAA;
> use Data::Dump qw(dump);
> my $a = {};
> bless $a, undef;
> say STDERR dump($a);
> }
>
> # Use of *uninitialized* value in bless
> # Explicit blessing to '' (assuming package main)
> # bless({}, "main")

Interesting. And, further:

{package BBB;
use Data::Dump qw(dump);
my $a = {};
bless $a;
say STDERR dump($a);
}

# bless({}, "BBB")

(1) bless already behaves differently with an undef
and with no second argument.

(2) The undef is treated as an empty string, not as no argument.

But myself, I would say that while the existing
warnings would seque well into being changed to
deprecation warnings, I personally wouldn't think
that the process is worth going through for this
particular feature.

I would still think a new function in Scalar::Util is
more appropriate.
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Jul 7, 2021, at 12:04 PM, Joseph Brenner <doomvox@gmail.com> wrote:
> […]
>
> (1) bless already behaves differently with an undef
> and with no second argument.
>
> (2) The undef is treated as an empty string, not as no argument.
>
> But myself, I would say that while the existing
> warnings would seque well into being changed to
> deprecation warnings, I personally wouldn't think
> that the process is worth going through for this
> particular feature.
>
> I would still think a new function in Scalar::Util is
> more appropriate.
>


My own view is that the current behavior with regard to ‘undef’ is not only undocumented, but silly and counterintuitive (with regard to the empty string, at least it’s consistent with $::x ). Changing it from silly to something that makes sense has value. (This is not the only place where passing an explicit undef is different than passing no argument.)

This would be how I would prefer to do things, but given that it would take two years to run through a deprecation cycle, and a new keyword could be added much more quickly to Scalar::Util, I can see how that would be advantageous.

--
Aaron Priven, aaron@priven.com, www.priven.com/aaron
Re: pre-pre-RFC: "unbless" [ In reply to ]
Joel Roth<joelz@pobox.com> wrote:

> Any code to do this will probably be where the class is
> defined, the implementation is known, and it will
> appropriate to explicity say bless $obj, 'HASH' when
> serializing

That's interesting, though currently something
blessed as 'HASH' isn't precisely the same as a plain
hash:

use Data::Dumper;
use feature qw( say );
my $h = {};
say "h: ", Dumper( $h );
# h: $VAR1 = {};

my $h2 = bless $h, 'HASH';
say "h2: ", Dumper( $h2 );
# h2: $VAR1 = bless( {}, 'HASH' );

Of course, if you weren't sure it was a hash, you
could do this:

use Scalar::Util qw( reftype );
my $h2 = bless $h_obj, reftype $h_obj;

While certainly you often know what kind of data
structure you're working on, there's also a need for
general purpose code that doesn't make any
assumptions about that-- for example, Data::Dumper.

Though notably, Data::Dumper is also recursive, which is
another angle to this discussion...
Re: pre-pre-RFC: "unbless" [ In reply to ]
I've chattered enough here for one day, I think, but just *one* more point:

Nicholas Clark<nick@ccl4.org> wrote:

> The big "feature" of Data::Structure::Util is that it's recursive.
> This suggestion isn't.

> The upshot, as Leon implies but doesn't say, is that as soon as one has a
> hash or array of objects to "output", one needs to manually write most of
> the traversal code to walk data structures, find the objects and unbless them.

It's perhaps an RFC for another day, but the need to
recurse down through a perl data structure comes up
often enough (Data::Dumper, is_deeply...) that it
might be a good idea to provide a general purpose
solution to this.

Notably, Raku has a "deepmap" function that descends
through a structure and returns a similar one with
modified values.
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Wed, Jul 7, 2021 at 4:03 PM Joseph Brenner <doomvox@gmail.com> wrote:

> I've chattered enough here for one day, I think, but just *one* more point:
>
> Nicholas Clark<nick@ccl4.org> wrote:
>
> > The big "feature" of Data::Structure::Util is that it's recursive.
> > This suggestion isn't.
>
> > The upshot, as Leon implies but doesn't say, is that as soon as one has a
> > hash or array of objects to "output", one needs to manually write most of
> > the traversal code to walk data structures, find the objects and unbless
> them.
>
> It's perhaps an RFC for another day, but the need to
> recurse down through a perl data structure comes up
> often enough (Data::Dumper, is_deeply...) that it
> might be a good idea to provide a general purpose
> solution to this.
>
> Notably, Raku has a "deepmap" function that descends
> through a structure and returns a similar one with
> modified values.
>

Not to say whether there should be a core solution for this, but just
noting the prior art: https://metacpan.org/pod/Data::Walk

-Dan

1 2  View All