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

1 2  View All