Mailing List Archive

pre-pre-RFC: "unbless"
This is my first attempt at birthing an RFC, so forgive me for not
doing this quite right.

I propose the introduction of an "unbless" functionality that simply
undoes what "bless" does.

Based on my research, there are 2 modules that do this:

* Data::Structure::Util (river pos. score of "2")
* Acme::Damn

There is another, but this doesn't really count:

* Function::Fallback::CoreOrPP (wrapper around A::D, falls back to
dclone)

Other than providing an inverse operation to "bless", there are
a couple of use cases that I can see this really providing some
benefit:

1. eliminate, for most cases, the need to define a TO_JSON in
objects that one is wishing to serialize; idk about anyone reading
this but implementing this method always seem to just work around
the issue and rebuild the hashref based on the blessed reference
(i.e., I don't use any 'unbless' from CPAN)

2. somewhat related to #1, but it would greatly simplify "modern"
web framework request handling (e.g., Dancer2) by both encouraging
organized code reflective of RESTful API (object/verb friendly)
but make it easy to easily just send a hash reference for
serialization by the content fileter (e.g., JSON).

Obvious Solutions:

a. find an existing module for dual-use, and include it with core;
perhaps add this to Scalar::Util (seems like a good fit).

b. implement "unbless" internally

Looking forward to any thoughts on this one. If there is a positive
reaction to my pre-pre-RFC; I'm happy doing the research to look
for evidence of wide spread use of:

* Data::Structure::Util
* TO_JSON implementations
* other serializations done by effective/manual "unblessing"

My suspicion is this is a common pain point; I know it is for me.
And if we had an 'unbless' that was easily at hand, I would be
using it a lot and writing much less code to do something I know
should be available in a default installation of Perl.

Cheers,
Brett

--
--
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 ]
I would very much like unbless as a builtin and for it to take a list of objects and unbless all of them.

I've also suggested, in the past, that blessing something into undef should have the effect of unblessing it. That would avoid adding a new keyword, but it would change the current behaviour (if anyone is doing that and ignoring the uninitialized value warning).


This email and any files transmitted with it are CONFIDENTIAL and are intended solely for the use of the individual(s) or entity to whom they are addressed. Any unauthorised copying, disclosure or distribution of the material within this email is strictly forbidden. Any views or opinions presented within this email are solely those of the author and do not necessarily represent those of PGIM Limited, QMA Wadhwani LLP or their affiliates unless otherwise specifically stated. An electronic message is not binding on its sender. Any message referring to a binding agreement must be confirmed in writing and duly signed. If you have received this email in error, please notify the sender immediately and delete the original. Telephone, electronic and other communications and conversations with PGIM Limited, QMA Wadhwani LLP and/or their associated persons may be recorded and retained. PGIM Limited and QMA Wadhwani LLP are authorised and regulated by the Financial Conduct Authority. PGIM Limited (registered in England No. 3809039) has its registered office at Grand Buildings, 1-3 Strand, Trafalgar Square, London WC2N 5HR and QMA Wadhwani LLP (registered in England No. OC303168) has its registered office at 9th Floor, Orion House, 5 Upper St. Martin's Lane, London, England, WC2H 9EA.

Please note that your personal information may be stored and processed in any country where we have facilities or in which we engage service providers. If you provide personal information to us by email or otherwise, you consent to the transfer of that information to countries outside of your country of residence and these countries may have different data protection rules than your country.

To learn about our privacy policies, please use this link<https://www.pgim.com/disclaimer/privacy-center> to read the Privacy Notices.
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Mon, Jul 5, 2021 at 12:01 PM Oodler 577 via perl5-porters <
perl5-porters@perl.org> wrote:

> This is my first attempt at birthing an RFC, so forgive me for not
> doing this quite right.
>
> I propose the introduction of an "unbless" functionality that simply
> undoes what "bless" does.
>
> Based on my research, there are 2 modules that do this:
>
> * Data::Structure::Util (river pos. score of "2")
> * Acme::Damn
>
> There is another, but this doesn't really count:
>
> * Function::Fallback::CoreOrPP (wrapper around A::D, falls back to
> dclone)
>
> Other than providing an inverse operation to "bless", there are
> a couple of use cases that I can see this really providing some
> benefit:
>
> 1. eliminate, for most cases, the need to define a TO_JSON in
> objects that one is wishing to serialize; idk about anyone reading
> this but implementing this method always seem to just work around
> the issue and rebuild the hashref based on the blessed reference
> (i.e., I don't use any 'unbless' from CPAN)
>
> 2. somewhat related to #1, but it would greatly simplify "modern"
> web framework request handling (e.g., Dancer2) by both encouraging
> organized code reflective of RESTful API (object/verb friendly)
> but make it easy to easily just send a hash reference for
> serialization by the content fileter (e.g., JSON).
>
> Obvious Solutions:
>
> a. find an existing module for dual-use, and include it with core;
> perhaps add this to Scalar::Util (seems like a good fit).
>
> b. implement "unbless" internally
>
> Looking forward to any thoughts on this one. If there is a positive
> reaction to my pre-pre-RFC; I'm happy doing the research to look
> for evidence of wide spread use of:
>
> * Data::Structure::Util
> * TO_JSON implementations
> * other serializations done by effective/manual "unblessing"
>
> My suspicion is this is a common pain point; I know it is for me.
> And if we had an 'unbless' that was easily at hand, I would be
> using it a lot and writing much less code to do something I know
> should be available in a default installation of Perl.
>

I absolutely agree this should be available from core. It's not often
needed, but when it is, it's weird that a CPAN module needs to be used.
However, due to the rarity of the need, I think it would be appropriate for
it to be in Scalar::Util rather than getting into features and builtins.

-Dan
Re: pre-pre-RFC: "unbless" [ In reply to ]
Or *unbless* as in *Data::Table::Text *see:

https://metacpan.org/pod/Data::Table::Text#unbless($d)

I use unbless to simplify testing and when converting/transmitting data to
other environments. It would also be helpful if a reference could be
blessed into several packages simultaneously with method selection
determined by the order of blessing.

On Mon, Jul 5, 2021 at 6:33 PM Dan Book <grinnz@gmail.com> wrote:

> On Mon, Jul 5, 2021 at 12:01 PM Oodler 577 via perl5-porters <
> perl5-porters@perl.org> wrote:
>
>> This is my first attempt at birthing an RFC, so forgive me for not
>> doing this quite right.
>>
>> I propose the introduction of an "unbless" functionality that simply
>> undoes what "bless" does.
>>
>> Based on my research, there are 2 modules that do this:
>>
>> * Data::Structure::Util (river pos. score of "2")
>> * Acme::Damn
>>
>> There is another, but this doesn't really count:
>>
>> * Function::Fallback::CoreOrPP (wrapper around A::D, falls back to
>> dclone)
>>
>> Other than providing an inverse operation to "bless", there are
>> a couple of use cases that I can see this really providing some
>> benefit:
>>
>> 1. eliminate, for most cases, the need to define a TO_JSON in
>> objects that one is wishing to serialize; idk about anyone reading
>> this but implementing this method always seem to just work around
>> the issue and rebuild the hashref based on the blessed reference
>> (i.e., I don't use any 'unbless' from CPAN)
>>
>> 2. somewhat related to #1, but it would greatly simplify "modern"
>> web framework request handling (e.g., Dancer2) by both encouraging
>> organized code reflective of RESTful API (object/verb friendly)
>> but make it easy to easily just send a hash reference for
>> serialization by the content fileter (e.g., JSON).
>>
>> Obvious Solutions:
>>
>> a. find an existing module for dual-use, and include it with core;
>> perhaps add this to Scalar::Util (seems like a good fit).
>>
>> b. implement "unbless" internally
>>
>> Looking forward to any thoughts on this one. If there is a positive
>> reaction to my pre-pre-RFC; I'm happy doing the research to look
>> for evidence of wide spread use of:
>>
>> * Data::Structure::Util
>> * TO_JSON implementations
>> * other serializations done by effective/manual "unblessing"
>>
>> My suspicion is this is a common pain point; I know it is for me.
>> And if we had an 'unbless' that was easily at hand, I would be
>> using it a lot and writing much less code to do something I know
>> should be available in a default installation of Perl.
>>
>
> I absolutely agree this should be available from core. It's not often
> needed, but when it is, it's weird that a CPAN module needs to be used.
> However, due to the rarity of the need, I think it would be appropriate for
> it to be in Scalar::Util rather than getting into features and builtins.
>
> -Dan
>
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Mon, Jul 5, 2021 at 12:01 PM Oodler 577 via perl5-porters
<perl5-porters@perl.org> wrote:

[...]

> Based on my research, there are 2 modules that do this:
>
> * Data::Structure::Util (river pos. score of "2")
> * Acme::Damn

This is a weak but positive sign that this kind of feature is wanted.
Did you grep
through the 34 dependencies of Data::Structure::Util to see how many of them
use the `unbless` function? Of the 8 modules that depend on Acme::Damn, only
forks.pm looks somewhat serious in it's desire for production usage (IMO).

I could see having something like `unbless` as a tool for debugging object
state, but it has some limitations.

[...]

>
> 1. eliminate, for most cases, the need to define a TO_JSON in
> objects that one is wishing to serialize; idk about anyone reading
> this but implementing this method always seem to just work around
> the issue and rebuild the hashref based on the blessed reference
> (i.e., I don't use any 'unbless' from CPAN)

First (and least of all) this argument depends on knowing you're never going to
unbless a coderef, file handle, format or any of the other things Perl can
bless into an object that won't naturally be serializable.

Second, the point of encapsulation is to hide the implementation details of an
object. Behavior vs. State is an implementation detail that the consumer of the
object shouldn't care about. The power of a TO_JSON method is so that you can
build a representation of the object without having to expose behavior vs.
state. Take the following (really bad) example:

(I am using Moose here, these choices are identical in any object framework
they just may be spelt differently)

```
use 5.34.0;
use experimental qw(signatures);

package MetricsReport {
use Moose;
use HTTP::Thin::UserAgent;

has uri => ( is => 'ro', required => 1 );

my sub get_data ($self) { http(GET $self->uri)->json->decoded_content }

sub aggregates ($self) {
my %aggs

# expects data to be a list of [name, value] tuples
$aggs{$_[0]} += $_[1] for keys $self->get_data->@*;

return \%aggs;
}
}

say JSON::MaybeXS->encode(unbless(RemoteReport->new( uri =>
'http://exmaple.com/report' )));
```

In this case `unless` would only see a hash with a uri. If calling the HTTP
request every time we want a report becomes problematic and we want to refactor
that into a cached value:

```
use 5.34.0;
use experimental qw(signatures);

package MetricsReport {
use Moose;
use HTTP::Thin::UserAgent;

has uri => ( is => 'ro', required => 1 );

has data => (
reader => 'get_data',
initarg => undef,
lazy => 1,
builder => sub ($self) { http(GET $self->uri)->json->decoded_Content }
);

sub aggregates ($self) {
my %aggs

# expects data to be a list of [name, value] tuples
$aggs{$_[0]} += $_[1] for keys $self->get_data->@*;

return \%aggs;
}
}

say JSON::MaybeXS->encode(unbless(RemoteReport->new( uri =>
'http://exmaple.com/stats' )));
```

Now `unbless` will see a different value depending on whether `data` has been
called yet or not. Maybe you add a block like this at the end:

```
my $r = RemoteReport->new(uri => 'http://example.com/stats');
$r->get_data;
my $data = unbless($r);
$data->{aggregates} = $r->aggregates;
say JSON::MaybeXS->encode($data)
```

But with TO_JSON you have the following:

```
use 5.34.0;
use experimental qw(signatures);

package MetricsReport {
use Moose;
use HTTP::Thin::UserAgent;

has uri => ( is => 'ro', required => 1 );

has data => (
reader => 'get_data',
initarg => undef,
lazy => 1,
builder => sub ($self) { http(GET $self->uri)->json->decoded_Content }
);

sub aggregates ($self) {
my %aggs

# expects data to be a list of [name, value] tuples
$aggs{$_[0]} += $_[1] for keys $self->get_data->@*;

return \%aggs;
}

sub TO_JSON ($self) {
return {
uri => $self->uri,
raw_data => $self->get_data,
aggregates => $self->aggregates,
}
}
}

say JSON::MaybeXS->new(allow_blessed => 1)
->encode(RemoteReport->new( uri => 'http://exmaple.com/stats' ));
```

The state of the object is entirely encapsulated _within_ the class, including
the representation of the object as JSON. Now `unbless` as a tool in the
service of `TO_JSON` I could see being _incredibly_ useful.

But as Dan says elsethread, I could see it being in Scalar::Util
rather than in core.

> 2. somewhat related to #1, but it would greatly simplify "modern"
> web framework request handling (e.g., Dancer2) by both encouraging
> organized code reflective of RESTful API (object/verb friendly)
> but make it easy to easily just send a hash reference for
> serialization by the content fileter (e.g., JSON).

I hope my example above explains why the somewhat relation to #1 makes this
problematic as well. Any time you have an object that has behavior whose output
you need in the Resource's representation you'll need to re-invent TO_JSON.

This isn't even getting into the Object/Resource problem that is similar to
the Object/Relational problem with ORMs, or the problem with XML and
Perl's Data Structures
(See: https://metacpan.org/pod/XML::Generator::PerlData#CAVEATS), which suggest
that blindly unwrapping an object and returning it's guts as the Resource may
cause problems in the long run anyway.

-Chris
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Mon, Jul 5, 2021 at 1:47 PM Philip R Brenan <philiprbrenan@gmail.com> wrote:
>
> Or unbless as in Data::Table::Text see:
>
> https://metacpan.org/pod/Data::Table::Text#unbless($d)
>
> I use unbless to simplify testing and when converting/transmitting data to other environments. It would also be helpful if a reference could be blessed into several packages simultaneously with method selection determined by the order of blessing.

our __PACKAGE__::QuickAndDirtyHack::ISA = qw(Several Packages We Want
InOrder); bless $foo, __PACKAGE__::QuickAndDirtyHack;

?
Re: pre-pre-RFC: "unbless" [ In reply to ]
Oodler 577 via perl5-porters writes:

> This is my first attempt at birthing an RFC, so forgive me for not
> doing this quite right.

Thank you for bringing up this suggestion.

> Other than providing an inverse operation to "bless", there are a
> couple of use cases that I can see this really providing some benefit:
>
> 1. eliminate, for most cases, the need to define a TO_JSON in
> objects that one is wishing to serialize
>
> 2. somewhat related to #1, but it would greatly simplify "modern"
> web framework request handling (e.g., Dancer2)

Somebody dealing with json or Dancer is already using Cpan modules, so
why would it be important that this specific functionality be installed
by default?

There'd be an advantage to having a module with a clear name (damn is a
little cutesy, in that somebody searching for the opposite to bless
would be unlikely to think of it), and perhaps for json and web
framework distributions to do one or more of depending on it,
re-exporting its function for users, documenting its existence, or
recommending it.

If you had that, what further gain is there by having unbless be in a
module bundled with core?

Thanks.

Smylers
Re: pre-pre-RFC: "unbless" [ In reply to ]
* Smylers <Smylers@stripey.com> [2021-07-05 18:55:09 +0100]:

> Oodler 577 via perl5-porters writes:
>
> > This is my first attempt at birthing an RFC, so forgive me for not
> > doing this quite right.
>
> Thank you for bringing up this suggestion.

You're welcome. I am happy to see the traction. It was a surprise. :-)

>
> > Other than providing an inverse operation to "bless", there are a
> > couple of use cases that I can see this really providing some benefit:
> >
> > 1. eliminate, for most cases, the need to define a TO_JSON in
> > objects that one is wishing to serialize
> >
> > 2. somewhat related to #1, but it would greatly simplify "modern"
> > web framework request handling (e.g., Dancer2)
>
> Somebody dealing with json or Dancer is already using Cpan modules, so
> why would it be important that this specific functionality be installed
> by default?
>
> There'd be an advantage to having a module with a clear name (damn is a
> little cutesy, in that somebody searching for the opposite to bless
> would be unlikely to think of it), and perhaps for json and web
> framework distributions to do one or more of depending on it,
> re-exporting its function for users, documenting its existence, or
> recommending it.

C<un>-doing something has precedence - C<unshift>, C<unpack> come to mind.

The web framework was an example that came to mind; but really I've run
into this quite a bit when doing any kind of serialization - which is large
area since it includes all text-based protocols (not just http) and things
built on top of them. It also makes it easier to dump things to file (e.g.,
Data::Dumper or Storable).

But serialization is not the only case I can think I'd use it. I've been
using Util::H2O quite a bit, and since it's super useful interstitially
to create ad hoc objects "in flight", it'd also be handy to unbless it.
Basically, I see Util::H2O::h2o as a "better bless", but I do not think
that an "unbless" is its responsibility.

>
> If you had that, what further gain is there by having unbless be in a
> module bundled with core?

I'm encouraged by the response. If I get a clear :thumbsup: from PSC or
and "editor" and an RFC number, I'd be happy to do the official write up.

From there, I don't think I have much of an opinion regarding it being a
built-in or in Scalar::Util; I'd use it either way.

I can also test out my idea for what it means for one to help "sheperd"
an RFC through the process.

HTH,
Brett

>
> Thanks.
>
> Smylers
>
>

--
--
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 ]
* Chris Prather <chris@prather.org> [2021-07-05 13:47:57 -0400]:

> On Mon, Jul 5, 2021 at 12:01 PM Oodler 577 via perl5-porters
> <perl5-porters@perl.org> wrote:
>
> [...]
>
> > Based on my research, there are 2 modules that do this:
> >
> > * Data::Structure::Util (river pos. score of "2")
> > * Acme::Damn
>
> This is a weak but positive sign that this kind of feature is wanted.
> Did you grep
> through the 34 dependencies of Data::Structure::Util to see how many of them
> use the `unbless` function? Of the 8 modules that depend on Acme::Damn, only
> forks.pm looks somewhat serious in it's desire for production usage (IMO).

That was the next step. I've been sufficiently encouraged to start digging.

As always, thank you for the insightful information in the rest of the email.
I need to spend more time reading through it, but wanted to reply to the
question of code spelunking.

Cheers,
Brett

>
> I could see having something like `unbless` as a tool for debugging object
> state, but it has some limitations.
>
> [...]
>
> >
> > 1. eliminate, for most cases, the need to define a TO_JSON in
> > objects that one is wishing to serialize; idk about anyone reading
> > this but implementing this method always seem to just work around
> > the issue and rebuild the hashref based on the blessed reference
> > (i.e., I don't use any 'unbless' from CPAN)
>
> First (and least of all) this argument depends on knowing you're never going to
> unbless a coderef, file handle, format or any of the other things Perl can
> bless into an object that won't naturally be serializable.
>
> Second, the point of encapsulation is to hide the implementation details of an
> object. Behavior vs. State is an implementation detail that the consumer of the
> object shouldn't care about. The power of a TO_JSON method is so that you can
> build a representation of the object without having to expose behavior vs.
> state. Take the following (really bad) example:
>
> (I am using Moose here, these choices are identical in any object framework
> they just may be spelt differently)
>
> ```
> use 5.34.0;
> use experimental qw(signatures);
>
> package MetricsReport {
> use Moose;
> use HTTP::Thin::UserAgent;
>
> has uri => ( is => 'ro', required => 1 );
>
> my sub get_data ($self) { http(GET $self->uri)->json->decoded_content }
>
> sub aggregates ($self) {
> my %aggs
>
> # expects data to be a list of [name, value] tuples
> $aggs{$_[0]} += $_[1] for keys $self->get_data->@*;
>
> return \%aggs;
> }
> }
>
> say JSON::MaybeXS->encode(unbless(RemoteReport->new( uri =>
> 'http://exmaple.com/report' )));
> ```
>
> In this case `unless` would only see a hash with a uri. If calling the HTTP
> request every time we want a report becomes problematic and we want to refactor
> that into a cached value:
>
> ```
> use 5.34.0;
> use experimental qw(signatures);
>
> package MetricsReport {
> use Moose;
> use HTTP::Thin::UserAgent;
>
> has uri => ( is => 'ro', required => 1 );
>
> has data => (
> reader => 'get_data',
> initarg => undef,
> lazy => 1,
> builder => sub ($self) { http(GET $self->uri)->json->decoded_Content }
> );
>
> sub aggregates ($self) {
> my %aggs
>
> # expects data to be a list of [name, value] tuples
> $aggs{$_[0]} += $_[1] for keys $self->get_data->@*;
>
> return \%aggs;
> }
> }
>
> say JSON::MaybeXS->encode(unbless(RemoteReport->new( uri =>
> 'http://exmaple.com/stats' )));
> ```
>
> Now `unbless` will see a different value depending on whether `data` has been
> called yet or not. Maybe you add a block like this at the end:
>
> ```
> my $r = RemoteReport->new(uri => 'http://example.com/stats');
> $r->get_data;
> my $data = unbless($r);
> $data->{aggregates} = $r->aggregates;
> say JSON::MaybeXS->encode($data)
> ```
>
> But with TO_JSON you have the following:
>
> ```
> use 5.34.0;
> use experimental qw(signatures);
>
> package MetricsReport {
> use Moose;
> use HTTP::Thin::UserAgent;
>
> has uri => ( is => 'ro', required => 1 );
>
> has data => (
> reader => 'get_data',
> initarg => undef,
> lazy => 1,
> builder => sub ($self) { http(GET $self->uri)->json->decoded_Content }
> );
>
> sub aggregates ($self) {
> my %aggs
>
> # expects data to be a list of [name, value] tuples
> $aggs{$_[0]} += $_[1] for keys $self->get_data->@*;
>
> return \%aggs;
> }
>
> sub TO_JSON ($self) {
> return {
> uri => $self->uri,
> raw_data => $self->get_data,
> aggregates => $self->aggregates,
> }
> }
> }
>
> say JSON::MaybeXS->new(allow_blessed => 1)
> ->encode(RemoteReport->new( uri => 'http://exmaple.com/stats' ));
> ```
>
> The state of the object is entirely encapsulated _within_ the class, including
> the representation of the object as JSON. Now `unbless` as a tool in the
> service of `TO_JSON` I could see being _incredibly_ useful.
>
> But as Dan says elsethread, I could see it being in Scalar::Util
> rather than in core.
>
> > 2. somewhat related to #1, but it would greatly simplify "modern"
> > web framework request handling (e.g., Dancer2) by both encouraging
> > organized code reflective of RESTful API (object/verb friendly)
> > but make it easy to easily just send a hash reference for
> > serialization by the content fileter (e.g., JSON).
>
> I hope my example above explains why the somewhat relation to #1 makes this
> problematic as well. Any time you have an object that has behavior whose output
> you need in the Resource's representation you'll need to re-invent TO_JSON.
>
> This isn't even getting into the Object/Resource problem that is similar to
> the Object/Relational problem with ORMs, or the problem with XML and
> Perl's Data Structures
> (See: https://metacpan.org/pod/XML::Generator::PerlData#CAVEATS), which suggest
> that blindly unwrapping an object and returning it's guts as the Resource may
> cause problems in the long run anyway.
>
> -Chris

--
--
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 ]
On Mon, Jul 5, 2021 at 2:32 PM Oodler 577 via perl5-porters <
perl5-porters@perl.org> wrote:

>
> From there, I don't think I have much of an opinion regarding it being a
> built-in or in Scalar::Util; I'd use it either way.
>

I think this brings up a separate question which I don't think has been
specifically answered so far: is the RFC process appropriate for adding
functions to core modules, rather than core features and syntax? It seems
superfluous to me, when modules (especially CPAN-upstream like
Scalar::Util) have their own process for evaluating new features, and
usually significantly less design considerations.

-Dan
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Mon, Jul 5, 2021 at 6:01 PM Oodler 577 via perl5-porters <
perl5-porters@perl.org> wrote:

> This is my first attempt at birthing an RFC, so forgive me for not
> doing this quite right.
>
> I propose the introduction of an "unbless" functionality that simply
> undoes what "bless" does.
>
> Based on my research, there are 2 modules that do this:
>
> * Data::Structure::Util (river pos. score of "2")
> * Acme::Damn
>
> There is another, but this doesn't really count:
>
> * Function::Fallback::CoreOrPP (wrapper around A::D, falls back to
> dclone)
>
> Other than providing an inverse operation to "bless", there are
> a couple of use cases that I can see this really providing some
> benefit:
>
> 1. eliminate, for most cases, the need to define a TO_JSON in
> objects that one is wishing to serialize; idk about anyone reading
> this but implementing this method always seem to just work around
> the issue and rebuild the hashref based on the blessed reference
> (i.e., I don't use any 'unbless' from CPAN)
>
> 2. somewhat related to #1, but it would greatly simplify "modern"
> web framework request handling (e.g., Dancer2) by both encouraging
> organized code reflective of RESTful API (object/verb friendly)
> but make it easy to easily just send a hash reference for
> serialization by the content fileter (e.g., JSON).
>
> Obvious Solutions:
>
> a. find an existing module for dual-use, and include it with core;
> perhaps add this to Scalar::Util (seems like a good fit).
>
> b. implement "unbless" internally
>
> Looking forward to any thoughts on this one. If there is a positive
> reaction to my pre-pre-RFC; I'm happy doing the research to look
> for evidence of wide spread use of:
>
> * Data::Structure::Util
> * TO_JSON implementations
> * other serializations done by effective/manual "unblessing"
>
> My suspicion is this is a common pain point; I know it is for me.
> And if we had an 'unbless' that was easily at hand, I would be
> using it a lot and writing much less code to do something I know
> should be available in a default installation of Perl.
>

IMO this is much too obscure to be a core keyword, and I would strongly
object to that.

I can imagine it existing in Scalar::Util, though I'm still not entirely
convinced this isn't an anti-pattern to begin with.

Leon
Re: pre-pre-RFC: "unbless" [ In reply to ]
* Dan Book <grinnz@gmail.com> [2021-07-05 14:43:06 -0400]:

> On Mon, Jul 5, 2021 at 2:32 PM Oodler 577 via perl5-porters <
> perl5-porters@perl.org> wrote:
>
> >
> > From there, I don't think I have much of an opinion regarding it being a
> > built-in or in Scalar::Util; I'd use it either way.
> >
>
> I think this brings up a separate question which I don't think has been
> specifically answered so far: is the RFC process appropriate for adding
> functions to core modules, rather than core features and syntax? It seems
> superfluous to me, when modules (especially CPAN-upstream like
> Scalar::Util) have their own process for evaluating new features, and
> usually significantly less design considerations.
>
> -Dan

Yeah, good question.

If allowed to proceed with an RFC, one of the questions to explore
would most certainly be "where?". And upon consenus (if clear), then
"how?". The process to get it in "core" would certainly be different
than to get it into a dual life module.

Cheers,
Brett

--
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 ]
* Leon Timmermans <fawaka@gmail.com> [2021-07-05 20:44:32 +0200]:

> On Mon, Jul 5, 2021 at 6:01 PM Oodler 577 via perl5-porters <
> perl5-porters@perl.org> wrote:
>
> > This is my first attempt at birthing an RFC, so forgive me for not
> > doing this quite right.
> >
> > I propose the introduction of an "unbless" functionality that simply
> > undoes what "bless" does.
> >
> > Based on my research, there are 2 modules that do this:
> >
> > * Data::Structure::Util (river pos. score of "2")
> > * Acme::Damn
> >
> > There is another, but this doesn't really count:
> >
> > * Function::Fallback::CoreOrPP (wrapper around A::D, falls back to
> > dclone)
> >
> > Other than providing an inverse operation to "bless", there are
> > a couple of use cases that I can see this really providing some
> > benefit:
> >
> > 1. eliminate, for most cases, the need to define a TO_JSON in
> > objects that one is wishing to serialize; idk about anyone reading
> > this but implementing this method always seem to just work around
> > the issue and rebuild the hashref based on the blessed reference
> > (i.e., I don't use any 'unbless' from CPAN)
> >
> > 2. somewhat related to #1, but it would greatly simplify "modern"
> > web framework request handling (e.g., Dancer2) by both encouraging
> > organized code reflective of RESTful API (object/verb friendly)
> > but make it easy to easily just send a hash reference for
> > serialization by the content fileter (e.g., JSON).
> >
> > Obvious Solutions:
> >
> > a. find an existing module for dual-use, and include it with core;
> > perhaps add this to Scalar::Util (seems like a good fit).
> >
> > b. implement "unbless" internally
> >
> > Looking forward to any thoughts on this one. If there is a positive
> > reaction to my pre-pre-RFC; I'm happy doing the research to look
> > for evidence of wide spread use of:
> >
> > * Data::Structure::Util
> > * TO_JSON implementations
> > * other serializations done by effective/manual "unblessing"
> >
> > My suspicion is this is a common pain point; I know it is for me.
> > And if we had an 'unbless' that was easily at hand, I would be
> > using it a lot and writing much less code to do something I know
> > should be available in a default installation of Perl.
> >
>
> IMO this is much too obscure to be a core keyword, and I would strongly
> object to that.
>
> I can imagine it existing in Scalar::Util, though I'm still not entirely
> convinced this isn't an anti-pattern to begin with.

I'd love to hear more on this "anti-pattern" question, if this RFC gets
the nod.

Cheers,
Brett

>
> Leon

--
--
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 ]
On Mon, Jul 5, 2021 at 5:09 PM Ed Avis <ed.avis@qmaw.com> wrote:

> I've also suggested, in the past, that blessing something into undef
> should have the effect of unblessing it. That would avoid adding a new
> keyword, but it would change the current behaviour (if anyone is doing that
> and ignoring the uninitialized value warning).
>

IMO this is a reasonable and intuitive suggestion which we could do without
breaking changes, I find it exceedingly unlikely that any module relies on
blessing to undef (though we should of course verify this on CPAN before
proceeding). This also would be a very simple change so probably could be a
simple PR for discussion.

-Dan
Re: pre-pre-RFC: "unbless" [ In reply to ]
From the keyboard of Oodler 577 via perl5-porters [05.07.21,18:31]:

> * Smylers <Smylers@stripey.com> [2021-07-05 18:55:09 +0100]:
>
>> Oodler 577 via perl5-porters writes:
[...]
>>
>> There'd be an advantage to having a module with a clear name (damn is a
>> little cutesy, in that somebody searching for the opposite to bless
>> would be unlikely to think of it), and perhaps for json and web
>> framework distributions to do one or more of depending on it,
>> re-exporting its function for users, documenting its existence, or
>> recommending it.
>
> C<un>-doing something has precedence - C<unshift>, C<unpack> come to mind.

Yes, since this is undoing something done.
BTW, Acme::Damn lets you import the 'curse' function under any name you'd
like, but unbless is the most succinct one.

[...]
> But serialization is not the only case I can think I'd use it. I've been
> using Util::H2O quite a bit, and since it's super useful interstitially
> to create ad hoc objects "in flight", it'd also be handy to unbless it.
> Basically, I see Util::H2O::h2o as a "better bless", but I do not think
> that an "unbless" is its responsibility.

Not the unbless() function, but using it for sure. Since it gets a hashref
and makes it into an object and sports a DESTROY which deletes the objects
package via Symbol::delete_package(), it should also undo the blessing and
make the blessed hash into an unblessed one, just as it has been before.

0--gg-

--
_($_=" "x(1<<5)."?\n".q?/)Oo. G?\ /
/\_?/(q /
---------------------------- \__(m.====?.(_("always off the crowd"))."?
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Mon, Jul 5, 2021 at 10:46 PM Oodler 577 <oodler577@sdf-eu.org> wrote:

> > I can imagine it existing in Scalar::Util, though I'm still not entirely
> > convinced this isn't an anti-pattern to begin with.
>
> I'd love to hear more on this "anti-pattern" question, if this RFC gets
> the nod.
>

This is a destructive operation. I have a hard time imagining any situation
in which I want the unblessed structure of an object, but don't want to
continue using the object. Also it breaks the destructor of that object. I
don't see this replacing TO_JSON methods.

Secondly, an object is likely to contain other objects, and those will
still need to be handled manually. At that point it doesn't seem so
advantageous anymore.

Basically, it seems like the wrong solution to a real problem.

Leon
Re: pre-pre-RFC: "unbless" [ In reply to ]
On Mon, 5 Jul 2021 13:33:19 -0400
Dan Book <grinnz@gmail.com> wrote:

> I absolutely agree this should be available from core. It's not often
> needed, but when it is, it's weird that a CPAN module needs to be
> used. However, due to the rarity of the need, I think it would be
> appropriate for it to be in Scalar::Util rather than getting into
> features and builtins.

I'm on holiday now so I'll likely forget, but if someone sends me a bug
report against Scalar::Util I'll write it when I get home.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: pre-pre-RFC: "unbless" [ In reply to ]
* Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> [2021-07-05 22:52:01 +0100]:

> On Mon, 5 Jul 2021 13:33:19 -0400
> Dan Book <grinnz@gmail.com> wrote:
>
> > I absolutely agree this should be available from core. It's not often
> > needed, but when it is, it's weird that a CPAN module needs to be
> > used. However, due to the rarity of the need, I think it would be
> > appropriate for it to be in Scalar::Util rather than getting into
> > features and builtins.
>
> I'm on holiday now so I'll likely forget, but if someone sends me a bug
> report against Scalar::Util I'll write it when I get home.

Aesome, thank you; I am happy to do it - question:

* https://metacpan.org/pod/Scalar::Util "Issues" points to
-> https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-List-Utils

* https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-Util doesn't exist

* https://github.com/Dual-Life/Scalar-List-Utils has no "Issues" tracker

So, where do I create the issue?

Cheers,
Brett

>
> --
> Paul "LeoNerd" Evans
>
> leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
> http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/

--
--
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 ]
Oodler 577 via perl5-porters <perl5-porters@perl.org> writes:

> Aesome, thank you; I am happy to do it - question:
>
> * https://metacpan.org/pod/Scalar::Util "Issues" points to
> -> https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-List-Utils
>
> * https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-Util doesn't exist
>
> * https://github.com/Dual-Life/Scalar-List-Utils has no "Issues" tracker
>
> So, where do I create the issue?

I would suggest the one that exists.

- ilmari
Re: pre-pre-RFC: "unbless" [ In reply to ]
ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) writes:

> Oodler 577 via perl5-porters <perl5-porters@perl.org> writes:
>
>> Aesome, thank you; I am happy to do it - question:
>>
>> * https://metacpan.org/pod/Scalar::Util "Issues" points to
>> -> https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-List-Utils
>>
>> * https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-Util doesn't exist
>>
>> * https://github.com/Dual-Life/Scalar-List-Utils has no "Issues" tracker
>>
>> So, where do I create the issue?
>
> I would suggest the one that exists.

Sorry, that was too snarky. I had forgotten that the new version of RT
doesn't show any hint on the individual distributions' queue for how to
report a bug if you're not logged in.

If you hover over the "About rt.cpan.org" item in the top navigation and
then clic "How do I ...?", it takes you to the usage page
(https://rt.cpan.org/NoAuth/RT/CPAN/Usage.html) which explains that you
can submit bugs by email to bug-<distribution-name>@rt.cpan.org,
i.e. bug-Scalar-List-Utils@rt.cpan.org in this case.

Or you can log in by clicking the unintuitively named "Log out guest
user" link at the top.

- ilmari
Re: pre-pre-RFC: "unbless" [ In reply to ]
* Dagfinn Ilmari Mannsker <ilmari@ilmari.org> [2021-07-05 23:54:42 +0100]:

> ilmari@ilmari.org (Dagfinn Ilmari Manns?ker) writes:
>
> > Oodler 577 via perl5-porters <perl5-porters@perl.org> writes:
> >
> >> Aesome, thank you; I am happy to do it - question:
> >>
> >> * https://metacpan.org/pod/Scalar::Util "Issues" points to
> >> -> https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-List-Utils
> >>
> >> * https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-Util doesn't exist
> >>
> >> * https://github.com/Dual-Life/Scalar-List-Utils has no "Issues" tracker
> >>
> >> So, where do I create the issue?
> >
> > I would suggest the one that exists.
>
> Sorry, that was too snarky. I had forgotten that the new version of RT
> doesn't show any hint on the individual distributions' queue for how to
> report a bug if you're not logged in.
>
> If you hover over the "About rt.cpan.org" item in the top navigation and
> then clic "How do I ...?", it takes you to the usage page
> (https://rt.cpan.org/NoAuth/RT/CPAN/Usage.html) which explains that you
> can submit bugs by email to bug-<distribution-name>@rt.cpan.org,
> i.e. bug-Scalar-List-Utils@rt.cpan.org in this case.
>
> Or you can log in by clicking the unintuitively named "Log out guest
> user" link at the top.
>
> - ilmari

Not a problem, though I am confused since everything is pointing to
Scalar::List::Utils, not Scalar::Util.

Is Scalar::Util "unituitively" under Scalar::List::Utils?

If that's the case, fine - please confirm.

Cheers,
Brett

--
--
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 ]
On Tue, 6 Jul 2021, at 00:00, Oodler 577 wrote:
> * Dagfinn Ilmari Mannsker <ilmari@ilmari.org> [2021-07-05 23:54:42 +0100]:
>
> > ilmari@ilmari.org (Dagfinn Ilmari Mannsåker) writes:
> >
> > > Oodler 577 via perl5-porters <perl5-porters@perl.org> writes:
> > >
> > >> Aesome, thank you; I am happy to do it - question:
> > >>
> > >> * https://metacpan.org/pod/Scalar::Util "Issues" points to
> > >> -> https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-List-Utils
> > >>
> > >> * https://rt.cpan.org/Public/Dist/Display.html?Name=Scalar-Util doesn't exist
> > >>
> > >> * https://github.com/Dual-Life/Scalar-List-Utils has no "Issues" tracker
> > >>
> > >> So, where do I create the issue?
> > >
> > > I would suggest the one that exists.
> >
> > Sorry, that was too snarky. I had forgotten that the new version of RT
> > doesn't show any hint on the individual distributions' queue for how to
> > report a bug if you're not logged in.
> >
> > If you hover over the "About rt.cpan.org" item in the top navigation and
> > then clic "How do I ...?", it takes you to the usage page
> > (https://rt.cpan.org/NoAuth/RT/CPAN/Usage.html) which explains that you
> > can submit bugs by email to bug-<distribution-name>@rt.cpan.org,
> > i.e. bug-Scalar-List-Utils@rt.cpan.org in this case.
> >
> > Or you can log in by clicking the unintuitively named "Log out guest
> > user" link at the top.
> >
> > - ilmari
>
> Not a problem, though I am confused since everything is pointing to
> Scalar::List::Utils, not Scalar::Util.
>
> Is Scalar::Util "unituitively" under Scalar::List::Utils?
>
> If that's the case, fine - please confirm.

The distribution that contains Scalar::Util, List::Util etc. is
called Scalar-List-Utils, as indicated and linked to at the top of
https://metacpan.org/pod/Scalar::Util -> https://metacpan.org/dist/Scalar-List-Utils

- ilmari

> Cheers,
> Brett
>
> --
> --
> 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 ]
* Dagfinn Ilmari Mannsker <ilmari@ilmari.org> [2021-07-06 00:03:36 +0100]:

<snip>

>
> The distribution that contains Scalar::Util, List::Util etc. is
> called Scalar-List-Utils, as indicated and linked to at the top of
> https://metacpan.org/pod/Scalar::Util -> https://metacpan.org/dist/Scalar-List-Utils

Thank you,

https://rt.cpan.org/Ticket/Display.html?id=137257

Brett

--
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 ]
On Mon, Jul 05, 2021 at 11:39:14PM +0200, Leon Timmermans wrote:
> On Mon, Jul 5, 2021 at 10:46 PM Oodler 577 <oodler577@sdf-eu.org> wrote:
>
> > > I can imagine it existing in Scalar::Util, though I'm still not entirely
> > > convinced this isn't an anti-pattern to begin with.
> >
> > I'd love to hear more on this "anti-pattern" question, if this RFC gets
> > the nod.
> >
>
> This is a destructive operation. I have a hard time imagining any situation
> in which I want the unblessed structure of an object, but don't want to
> continue using the object. Also it breaks the destructor of that object. I
> don't see this replacing TO_JSON methods.
>
> Secondly, an object is likely to contain other objects, and those will
> still need to be handled manually. At that point it doesn't seem so
> advantageous anymore.

[Expanded below]

> Basically, it seems like the wrong solution to a real problem.

I'm tending to think this too. In that, the problem is legitimate, but this
approach looks like a hack that applies a big hammer to the symptoms,
rather than figuring out what was wrong with the design, and what the
correct use case should be, such that a hack isn't needed.

On Mon, Jul 05, 2021 at 04:01:00PM +0000, Oodler 577 via perl5-porters wrote:

> * Data::Structure::Util (river pos. score of "2")

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.

And as Leon says, it's a destructive operation.
The obvious "solution" to being destructive is to make a copy first.
At which point you don't need "unbless" anyway because you copy without
blessing.

> 1. eliminate, for most cases, the need to define a TO_JSON in
> objects that one is wishing to serialize; idk about anyone reading
> this but implementing this method always seem to just work around
> the issue and rebuild the hashref based on the blessed reference
> (i.e., I don't use any 'unbless' from CPAN)
>
> 2. somewhat related to #1, but it would greatly simplify "modern"
> web framework request handling (e.g., Dancer2) by both encouraging
> organized code reflective of RESTful API (object/verb friendly)
> but make it easy to easily just send a hash reference for
> serialization by the content fileter (e.g., JSON).

I'm not convinced that this is true. I think it's glossing over an important
implementation detail - incoming JSON booleans are converted to objects:

perl -MCpanel::JSON::XS -MData::Dumper -e 'print Dumper(decode_json("[true, false]"))'
$VAR1 = [.
bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' )
];


so if one writes a web service that takes JSON, and then using the approach
that you seem to be advocating (just unbless everything before output),
these booleans are *not* going to round trip.


Also, JSON can't serialise all things that Perl objects can contain.
Most blatantly, references to scalars:

perl -MCpanel::JSON::XS -lwe 'my $j = Cpanel::JSON::XS->new(); print $j->encode_json(\$a)
encountered object 'Cpanel::JSON::XS=SCALAR(0x55a2351715a8)', but neither allow_blessed, convert_blessed nor allow_tags settings are enabled (or TO_JSON/FREEZE method missing) at -e line 1.


There isn't actually anything "blessed" here - I think that this object in
the error message is part of the internal implementation.

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.

Nicholas Clark
Re: pre-pre-RFC: "unbless" [ In reply to ]
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.

Nicholas Clark
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