Skip Menu |
Report information
Id: 124428
Status: rejected
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: eda [at] waniasset.com
Cc:
AdminCc:

Operating System: Linux
PatchStatus: (no value)
Severity: Wishlist
Type: core
Perl Version: 5.18.4
Fixed In: (no value)



Subject: bless $x, undef to unbless
To: "perlbug [...] perl.org" <perlbug [...] perl.org>
From: Ed Avis <eda [...] waniasset.com>
Date: Thu, 30 Apr 2015 13:35:29 +0000
Download (untitled) / with headers
text/plain 6.9k
This is a bug report for perl from eda@waniasset.com, generated with the help of perlbug 1.39 running under perl 5.18.4. ----------------------------------------------------------------- [Please describe your issue here] Sometimes you need to unbless a scalar. Various CPAN modules exist to do this and various whimsical names such as 'curse' and 'smite', but it deserves to be in the core language. No new keyword is needed; instead you should be able to just bless $x, undef; to unbless scalar $x. Note that this is not the same thing as bless $x; which should continue to bless into the current package. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=wishlist --- Site configuration information for perl 5.18.4: Configured by Red Hat, Inc. at Thu Apr 2 16:17:20 UTC 2015. Summary of my perl5 (revision 5 version 18 subversion 4) configuration: Platform: osname=linux, osvers=3.19.1-201.fc21.x86_64, archname=x86_64-linux-thread-multi uname='linux buildvm-23.phx2.fedoraproject.org 3.19.1-201.fc21.x86_64 #1 smp wed mar 18 04:29:24 utc 2015 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Dccdlflags=-Wl,--enable-new-dtags -Dlddlflags=-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wl,-z,relro -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.18.4 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic', cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.8.3 20140911 (Red Hat 4.8.3-7)', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags =' -fstack-protector' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc -lgdbm_compat perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.18' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wl,-z,relro ' Locally applied patches: Fedora Patch1: Removes date check, Fedora/RHEL specific Fedora Patch3: support for libdir64 Fedora Patch4: use libresolv instead of libbind Fedora Patch5: USE_MM_LD_RUN_PATH Fedora Patch6: Skip hostname tests, due to builders not being network capable Fedora Patch7: Dont run one io test due to random builder failures Fedora Patch9: Fix find2perl to translate ? glob properly (RT#113054) Fedora Patch10: Update h2ph(1) documentation (RT#117647) Fedora Patch11: Update pod2html(1) documentation (RT#117623) Fedora Patch12: Disable ornaments on perl5db AutoTrace tests (RT#118817) Fedora Patch14: Do not use system Term::ReadLine::Gnu in tests (RT#118821) Fedora Patch15: Define SONAME for libperl.so Fedora Patch16: Install libperl.so to -Dshrpdir value Fedora Patch18: Fix crash with \\&$glob_copy (RT#119051) Fedora Patch19: Fix coreamp.t rand test (RT#118237) Fedora Patch20: Reap child in case where exception has been thrown (RT#114722) Fedora Patch21: Fix using regular expressions containing multiple code blocks (RT#117917) Fedora Patch22: Create site paths by cpan for the first time (CPAN RT#99905) Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux --- @INC for perl 5.18.4: /home/eda/lib/perl5/ /home/eda/lib64/perl5/ /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 . --- Environment for perl 5.18.4: HOME=/home/eda LANG=en_GB.UTF-8 LANGUAGE (unset) LC_COLLATE=C LC_CTYPE=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 LC_MONETARY=en_GB.UTF-8 LC_NUMERIC=en_GB.UTF-8 LC_TIME=en_GB.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/eda/bin:/home/eda/bin:/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/sbin:/usr/sbin PERL5LIB=/home/eda/lib/perl5/:/home/eda/lib64/perl5/ PERL_BADLANG (unset) SHELL=/bin/bash -- Ed Avis <eda@waniasset.com> This email is intended only for the person to whom it is addressed and may contain confidential information. Any retransmission, copying, disclosure or other use of, this information by persons other than the intended recipient is prohibited. If you received this email in error, please contact the sender and delete the material. This email is for information only and is not intended as an offer or solicitation for the purchase or sale of any financial instrument. Wadhwani Asset Management LLP is a Limited Liability Partnership registered in England (OC303168) with registered office at 40 Berkeley Square, 3rd Floor, London, W1J 5AL. It is authorised and regulated by the Financial Conduct Authority.
Subject: Re: [perl #124428] bless $x, undef to unbless
From: Kent Fredric <kentfredric [...] gmail.com>
Date: Fri, 1 May 2015 01:47:06 +1200
To: pp Porters <perl5-porters [...] perl.org>
CC: bugs-bitbucket [...] rt.perl.org

On 1 May 2015 at 01:35, Ed Avis <perlbug-followup@perl.org> wrote:
Show quoted text

    bless $x, undef;

to unbless scalar $x.

Incidentally, Acme::Damn makes that syntax available:

https://metacpan.org/pod/Acme::Damn#bless-reference-undef

Unfortunately, its not presently an "error" if somebody does this without it, and so:

   bless $x, undef
   bless $x, ''

Are both equivalent to

    bless $x, "main"


perl -MData::Dump=pp -wE 'package Boss; my $x = bless {}, undef; Data::Dump::pp $x'
Use of uninitialized value in bless at -e line 1.
Explicit blessing to '' (assuming package main) at -e line 1.
bless({}, "main")


Other than that, the proposal seems simple enough that I'm in favour of it.

I just can't tell the scope of if any code is foolishly relying on this existing behaviour, because grepping for it without a full parse is hard. ( And also, writing a critic policy to match this expression might be fun ): http://grep.cpan.me/?q=bless\W.{0%2C500}%3F%2C\s*undef

Obviously you can do damage prevention by making it a feature.

To: "'perlbug-followup [...] perl.org'" <perlbug-followup [...] perl.org>
Date: Thu, 30 Apr 2015 13:51:30 +0000
Subject: RE: [perl #124428] bless $x, undef to unbless
From: Ed Avis <eda [...] waniasset.com>
Download (untitled) / with headers
text/plain 1.1k
bless $x, undef will currently generate two warnings, if warnings are enabled: Use of uninitialized value in bless Explicit blessing to '' (assuming package main) For that reason I felt that changing the semantics would be reasonable. Oneliners may be written without warnings, but they rarely bless objects. For backwards compatibility I guess that bless $x, '' could continue to do what it does currently; only an explicit undef would cause the unblessing. -- Ed Avis <eda@waniasset.com> This email is intended only for the person to whom it is addressed and may contain confidential information. Any retransmission, copying, disclosure or other use of, this information by persons other than the intended recipient is prohibited. If you received this email in error, please contact the sender and delete the material. This email is for information only and is not intended as an offer or solicitation for the purchase or sale of any financial instrument. Wadhwani Asset Management LLP is a Limited Liability Partnership registered in England (OC303168) with registered office at 40 Berkeley Square, 3rd Floor, London, W1J 5AL. It is authorised and regulated by the Financial Conduct Authority.
Subject: Re: [perl #124428] bless $x, undef to unbless
CC: "perlbug-followup [...] perl.org" <perlbug-followup [...] perl.org>
To: Ed Avis <eda [...] waniasset.com>
Date: Thu, 30 Apr 2015 16:26:43 +0200
From: Ævar Arnfjörð Bjarmason <avarab [...] gmail.com>
Download (untitled) / with headers
text/plain 1001b
On Thu, Apr 30, 2015 at 3:51 PM, Ed Avis <eda@waniasset.com> wrote: Show quoted text
> bless $x, undef > > will currently generate two warnings, if warnings are enabled: > > Use of uninitialized value in bless > Explicit blessing to '' (assuming package main) > > For that reason I felt that changing the semantics would be reasonable. Oneliners may be written without warnings, but they rarely bless objects. > > For backwards compatibility I guess that > > bless $x, '' > > could continue to do what it does currently; only an explicit undef would cause the unblessing.
The main problem with this proposal is that now this code that warned before would silently unbless: bless $what{object}, $what{__PACKAGE__}; We could I guess generate a warning for trying to unbless an already unblessed thing, but are we going to add one too for: bless {} => "main" for 1..2 ? I think this makes more sense as a new function Scalar::Util or something. Or maybe we could just ship Acme::Damn ?:)
Date: Thu, 30 Apr 2015 14:30:10 +0000 (UTC)
To: perl5-porters [...] perl.org
From: Ed Avis <eda [...] waniasset.com>
Subject: Re: [perl #124428] bless $x, undef to unbless
Download (untitled) / with headers
text/plain 623b
Ævar Arnfjörð Bjarmason <avarab <at> gmail.com> writes: Show quoted text
>The main problem with this proposal is that now this code that warned >before would silently unbless: > > bless $what{object}, $what{__PACKAGE__};
The cautious approach would be to make a hard deprecation cycle. (1) blessing to undef becomes a runtime error (rather than just a warning as now). (2) a couple of releases later, blessing to undef gets the semantics of unblessing. I do think that C<bless $x, undef> is the logical way to express it and it shouldn't linger forever in Obscure::Scalar::Utils or Acme::Whatever. -- Ed Avis <eda@waniasset.com>
To: perl5-porters [...] perl.org
Date: Thu, 30 Apr 2015 15:42:41 +0100
From: "Paul \"LeoNerd\" Evans" <leonerd [...] leonerd.org.uk>
Subject: Re: [perl #124428] bless $x, undef to unbless
Download (untitled) / with headers
text/plain 453b
On Thu, 30 Apr 2015 16:26:43 +0200 Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote: Show quoted text
> I think this makes more sense as a new function Scalar::Util or > something.
As Scalar::Util's current maintainer, if anyone wants to throw me the obvious ~3 line XS patch + PP docs to make use Scalar::Util 'unbless'; I'll happily merge it. -- Paul "LeoNerd" Evans leonerd@leonerd.org.uk http://www.leonerd.org.uk/ | https://metacpan.org/author/PEVANS
Download (untitled)
application/pgp-signature 213b

Message body not shown because it is not plain text.

Date: Thu, 30 Apr 2015 14:46:49 +0000 (UTC)
To: perl5-porters [...] perl.org
Subject: Re: [perl #124428] bless $x, undef to unbless
From: Ed Avis <eda [...] waniasset.com>
Download (untitled) / with headers
text/plain 323b
unbless is already part of Data::Structure::Util (and other modules). Although the implementation there is a bit funky in that it recursively unblesses everything in the data structure - not what I would have done :-( That does mean that the name 'unbless' is already taken in some sense. -- Ed Avis <eda@waniasset.com>
From: Ævar Arnfjörð Bjarmason <avarab [...] gmail.com>
Date: Thu, 30 Apr 2015 16:48:39 +0200
CC: Perl 5 Porters <perl5-porters [...] perl.org>
To: Ed Avis <eda [...] waniasset.com>
Subject: Re: [perl #124428] bless $x, undef to unbless
On Thu, Apr 30, 2015 at 4:30 PM, Ed Avis <eda@waniasset.com> wrote: Show quoted text
> Ævar Arnfjörð Bjarmason <avarab <at> gmail.com> writes: >
>>The main problem with this proposal is that now this code that warned >>before would silently unbless: >> >> bless $what{object}, $what{__PACKAGE__};
> > The cautious approach would be to make a hard deprecation cycle. > (1) blessing to undef becomes a runtime error (rather than just a warning > as now). (2) a couple of releases later, blessing to undef gets the semantics > of unblessing. > > I do think that C<bless $x, undef> is the logical way to express it and it > shouldn't linger forever in Obscure::Scalar::Utils or Acme::Whatever.
Aside from backwards compatibility concerns I don't like this API design. We have tie() and untie(), not untying as some special parameter to tie(), similarly for link() and unlink() or mkdir() and rmdir() for that matter. I know there's good reasons for why some of those couldn't get extra parameters or special parameters like bless() could, but I find unbless() to be more logical. We already have the logical equivalent of do() an undo() functions, not undo() as some special parameter to do(). Also what should a function like this do? Objects are opaque and while we can just remove the blessedness I think if the core introduced something like this it would make more sense to make: unbless($obj); # or bless($obj, undef); .... Be: $obj = $obj->UNBLESS; # Or is that already ->FREEZE Which perhaps would fall back on a core method that would just remove the blessed flag if no "UNBLESS" sub was available. That way we could generalize "as_hash" and other "remove private garbage and return something sensible to reconstruct the object" which exists in almost any non-trivial Perl program. You could argue that it should do exactly nothing except remove the blessed flag, but the absence of this feature in Perl now means people don't expect their objects to go back to non-objects unless they explicitly have some "object export" feature. A core API change like this would have an effect on future code.
Subject: Re: [perl #124428] bless $x, undef to unbless
Date: Fri, 1 May 2015 02:49:21 +1200
From: Kent Fredric <kentfredric [...] gmail.com>
To: Ed Avis <eda [...] waniasset.com>
CC: pp Porters <perl5-porters [...] perl.org>

On 1 May 2015 at 02:30, Ed Avis <eda@waniasset.com> wrote:
Show quoted text

I do think that C<bless $x, undef> is the logical way to express it and it
shouldn't linger forever in Obscure::Scalar::Utils or Acme::Whatever.

Another thought against: making undef remove bless instead of casting it could be seen as special-casing.

A type of special casing that might put more burden on people using

    bless $x, $somename

Due to the need to propagate the special case when $somename is not defined by them.

Imagine:

   sub foo {
      my $class = shift;
      my $structure = bless {@_} , $class;
      die "unsupported" unless $x->can("foo") or $x->isa("Bar");
  }

Given that currently, that would mean

    foo(undef, @args );

Would presently create a valid object, allbeit one they've got handling code for it being invalid.

The new behaviour would create a non-object, which might croak/bail in confusing ways which requires additional handling.

That would be a step backwards.
Subject: Re: [perl #124428] bless $x, undef to unbless
To: perl5-porters [...] perl.org
From: "Paul \"LeoNerd\" Evans" <leonerd [...] leonerd.org.uk>
Date: Thu, 30 Apr 2015 15:49:16 +0100
Download (untitled) / with headers
text/plain 812b
On Thu, 30 Apr 2015 14:46:49 +0000 (UTC) Ed Avis <eda@waniasset.com> wrote: Show quoted text
> unbless is already part of Data::Structure::Util (and other modules). > Although the implementation there is a bit funky in that it > recursively unblesses everything in the data structure - not what I > would have done :-( That does mean that the name 'unbless' is already > taken in some sense.
That's OK - perl's naming structure means that two different packages can provide the same named function with different implementations. unbless is the sensible name for this function. Also it would be "surprising" to users if a "core"-style Scalar::Util::unbless were to recurse, so better to do the simple 3liner. -- Paul "LeoNerd" Evans leonerd@leonerd.org.uk http://www.leonerd.org.uk/ | https://metacpan.org/author/PEVANS
Download (untitled)
application/pgp-signature 213b

Message body not shown because it is not plain text.

Subject: Re: [perl #124428] bless $x, undef to unbless
CC: Ed Avis <eda [...] waniasset.com>, Perl 5 Porters <perl5-porters [...] perl.org>
To: Ævar Arnfjörð Bjarmason <avarab [...] gmail.com>
Date: Fri, 1 May 2015 02:55:13 +1200
From: Kent Fredric <kentfredric [...] gmail.com>
Download (untitled) / with headers
text/plain 707b

On 1 May 2015 at 02:48, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
Show quoted text

Be:

    $obj = $obj->UNBLESS; # Or is that already ->FREEZE


A disadvantage of that approach is that it would be unsafe to use on non-blessed values, leading to people needing to do one of the following:

   my $ref = blessed $original ? $original->UNBLESS : $original  # ew

   my $ref = UNIVERSAL::UNBLESS( $original ) ; # ew

   use Safe::Unbless;
  
   my $ref = $original->$_unbless;

That would still be the case if we defined unbless not to work on already unblessed objects.

But seeing bless works on already blessed objects, it would break the parity.

Subject: Re: [perl #124428] bless $x, undef to unbless
From: Ed Avis <eda [...] waniasset.com>
To: perl5-porters [...] perl.org
Date: Thu, 30 Apr 2015 14:58:05 +0000 (UTC)
Download (untitled) / with headers
text/plain 1.2k
Ævar Arnfjörð Bjarmason <avarab <at> gmail.com> writes: Show quoted text
>make: > > unbless($obj); # or bless($obj, undef); .... > > Be: > > $obj = $obj->UNBLESS; # Or is that already ->FREEZE
If you introduce that, then the UNBLESS method would also have to be called when an existing blessed object is re-blessed into a different class. Personally I would just like to set or unset the blessed field on the scalar, without any hidden methods being called. Show quoted text
>You could argue that it should do exactly nothing except remove the >blessed flag, but the absence of this feature in Perl now means people >don't expect their objects to go back to non-objects unless they >explicitly have some "object export" feature. A core API change like >this would have an effect on future code.
I don't quite understand what you are getting at here. After all, an object can already be re-blessed into a different class such that none of the original methods (not even DESTROY) will be called. How is unblessing any worse than reblessing into RandomUnrelatedPackage? package Foo; sub DESTROY { say 'destroy' } sub new { bless {} } package Bar; package main; my $f = new Foo; bless $f, 'Bar'; -- Ed Avis <eda@waniasset.com>
To: Ævar Arnfjörð Bjarmason <avarab [...] gmail.com>
Date: Thu, 30 Apr 2015 11:03:17 -0400
CC: Ed Avis <eda [...] waniasset.com>, Perl 5 Porters <perl5-porters [...] perl.org>
From: Ricardo Signes <perl.p5p [...] rjbs.manxome.org>
Subject: Re: [perl #124428] bless $x, undef to unbless
Download (untitled) / with headers
text/plain 883b
* Ævar Arnfjörð Bjarmason <avarab@gmail.com> [2015-04-30T10:48:39] Show quoted text
> Aside from backwards compatibility concerns I don't like this API design.
I agree with all of Ævar's objections. Show quoted text
> $obj = $obj->UNBLESS; # Or is that already ->FREEZE > > Which perhaps would fall back on a core method that would just remove > the blessed flag if no "UNBLESS" sub was available. That way we could > generalize "as_hash" and other "remove private garbage and return > something sensible to reconstruct the object" which exists in almost > any non-trivial Perl program.
I was really not sure about this, but the more I thought about it, the more that something like this seems important to provide. It's also plausible that the right solution is that UNIVERSAL::UNBLESS just calls Scalar::Util::unbless, and now you have a toolkit. I haven't given it a lot of thought (yet?). -- rjbs
Download signature.asc
application/pgp-signature 473b

Message body not shown because it is not plain text.

Subject: Re: [perl #124428] bless $x, undef to unbless
From: Ed Avis <eda [...] waniasset.com>
To: perl5-porters [...] perl.org
Date: Thu, 30 Apr 2015 15:01:54 +0000 (UTC)
Download (untitled) / with headers
text/plain 695b
An alternative proposal would be first to move Scalar::Util::blessed into the core language, and then make it an lvalue. blessed($x) = 'Foo'; # blesses $x into package Foo blessed($x) = undef; # unblesses $x But both this and C<bless $x, undef> work on a single scalar. One advantage of adding 'unbless' is that it can work on a list: unbless @a; # unblesses each element As it happens that is the use case I am thinking of - and it is in a hot path of my program, so if I could call a single builtin to deal with the whole list that would be better than writing a loop. So on reflection I think adding 'unbless' may be the best way. -- Ed Avis <eda@waniasset.com>
Date: Thu, 30 Apr 2015 15:07:11 +0000 (UTC)
To: perl5-porters [...] perl.org
From: Ed Avis <eda [...] waniasset.com>
Subject: Re: [perl #124428] bless $x, undef to unbless
Download (untitled) / with headers
text/plain 675b
I wouldn't necessarily want to call a method every time I unbless an object. Sure, that can be the default, but just as bless is purely a builtin operation, there should be some kind of raw_unbless which is equally simple and fast, and does nothing except unset the field on the scalar. I don't buy the argument that adding raw_unbless will somehow violate the language's contract with object-oriented libraries that don't expect their objects to suddenly get downgraded to ordinary references, because (a) there are already unbless implementations on CPAN, and (b) you can already rebless any existing object into some random other class. -- Ed Avis <eda@waniasset.com>
To: perl5-porters [...] perl.org
From: "Paul \"LeoNerd\" Evans" <leonerd [...] leonerd.org.uk>
Date: Thu, 30 Apr 2015 16:17:39 +0100
Subject: Re: [perl #124428] bless $x, undef to unbless
Download (untitled) / with headers
text/plain 800b
On Thu, 30 Apr 2015 15:01:54 +0000 (UTC) Ed Avis <eda@waniasset.com> wrote: Show quoted text
> An alternative proposal would be first to move Scalar::Util::blessed > into the core language, and then make it an lvalue. > > blessed($x) = 'Foo'; # blesses $x into package Foo > blessed($x) = undef; # unblesses $x
It doesn't need to be moved to be lvalue'able. It can have lvalue semantics just fine where it lives now. (I would prefer that it didn't though because Real Soon Now I'm going to make a super-optimised custom-op version of blessed that would then remove the ENTERSUB/XS call overhead; see https://github.com/Scalar-List-Utils/Scalar-List-Utils/tree/pevans-custom-ops ) -- Paul "LeoNerd" Evans leonerd@leonerd.org.uk http://www.leonerd.org.uk/ | https://metacpan.org/author/PEVANS
Download (untitled)
application/pgp-signature 213b

Message body not shown because it is not plain text.

Subject: Re: [perl #124428] bless $x, undef to unbless
From: Kent Fredric <kentfredric [...] gmail.com>
Date: Fri, 1 May 2015 03:18:10 +1200
To: Ed Avis <eda [...] waniasset.com>
CC: pp Porters <perl5-porters [...] perl.org>
Download (untitled) / with headers
text/plain 1.7k

On 1 May 2015 at 03:07, Ed Avis <eda@waniasset.com> wrote:
Show quoted text
I wouldn't necessarily want to call a method every time I unbless an object.
Sure, that can be the default, but just as bless is purely a builtin
operation, there should be some kind of raw_unbless which is equally
simple and fast, and does nothing except unset the field on the scalar.

I don't buy the argument that adding raw_unbless will somehow violate the
language's contract with object-oriented libraries that don't expect their
objects to suddenly get downgraded to ordinary references, because (a)
there are already unbless implementations on CPAN, and (b) you can already
rebless any existing object into some random other class.

I posit the frequency of using unbless is already low, and the desire for unbless to imply DESTROY is even lower.

Conflating those 2 behaviours together just means if you want one without the other, you don't have the choice, and we're back at square one.

The last thing you want is do go "ok, I'm going to just unbless things so they can be serialized" going "uh. ,.... and now the data is gone, great".

Similarly, using unbless on a list of objects seems infrequent enough that it would require evidence of a real usecase to justify that being there by design. ( Because it breaks parity, and limits future options ).

For instance, if unbless always took a list, then you're limiting your options later if you decide unbless can take parameters. ( Also not something I'd want, due to parity breaking , but just for example  ).

   my $hash = unbless $ref, { destroy => 1 };

^ would not be an option if:

- unbless supported a list
- unbless allowed passthrough of non-blesed objects ( similar to how bless doesnt' barf on blessed objects ).

Subject: Re: [perl #124428] bless $x, undef to unbless
From: demerphq <demerphq [...] gmail.com>
Date: Thu, 30 Apr 2015 20:21:58 +0200
To: Ricardo Signes <perl.p5p [...] rjbs.manxome.org>
CC: Ævar Arnfjörð <avarab [...] gmail.com>, Ed Avis <eda [...] waniasset.com>, Perl 5 Porters <perl5-porters [...] perl.org>
Download (untitled) / with headers
text/plain 1.9k
On 30 April 2015 at 17:03, Ricardo Signes <perl.p5p@rjbs.manxome.org> wrote: Show quoted text
> * Ævar Arnfjörð Bjarmason <avarab@gmail.com> [2015-04-30T10:48:39]
>> Aside from backwards compatibility concerns I don't like this API design.
> > I agree with all of Ævar's objections. >
>> $obj = $obj->UNBLESS; # Or is that already ->FREEZE >> >> Which perhaps would fall back on a core method that would just remove >> the blessed flag if no "UNBLESS" sub was available. That way we could >> generalize "as_hash" and other "remove private garbage and return >> something sensible to reconstruct the object" which exists in almost >> any non-trivial Perl program.
> > I was really not sure about this, but the more I thought about it, the more > that something like this seems important to provide. It's also plausible that > the right solution is that UNIVERSAL::UNBLESS just calls Scalar::Util::unbless, > and now you have a toolkit. > > I haven't given it a lot of thought (yet?).
I am opposed to $obj->UNBLESS; Methods are overridable, and I would consider a method call to "touch" the object, which could have any sort of consequence. If we think we want this we should just add unbless to the language like we have untie. IMO unbless should be usable on something like Object::Deadly without triggering any method calls. Also, I thing its weird to have a method call change the type of its invocant like this, not entirely unheard of, but weird. Also unblessing is a strange thing given that the *referent* not the reference is blessed, consider the action at a distance involved. One part of the code might accept an object, validate that it has indeed received an object, but then at some far distant point in the code the object could be unblessed, leaving a non-object in memory, resulting in strange consequences. Of course this also applies to *reblessing* too, but still, we already have that problem, we dont "officially" have the problem of unbless. Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"
Date: Thu, 30 Apr 2015 20:24:28 +0200
From: demerphq <demerphq [...] gmail.com>
CC: Ævar Arnfjörð <avarab [...] gmail.com>, Ed Avis <eda [...] waniasset.com>, Perl 5 Porters <perl5-porters [...] perl.org>
To: Ricardo Signes <perl.p5p [...] rjbs.manxome.org>
Subject: Re: [perl #124428] bless $x, undef to unbless
Download (untitled) / with headers
text/plain 2.2k
On 30 April 2015 at 20:21, demerphq <demerphq@gmail.com> wrote: Show quoted text
> On 30 April 2015 at 17:03, Ricardo Signes <perl.p5p@rjbs.manxome.org> wrote:
>> * Ævar Arnfjörð Bjarmason <avarab@gmail.com> [2015-04-30T10:48:39]
>>> Aside from backwards compatibility concerns I don't like this API design.
>> >> I agree with all of Ævar's objections. >>
>>> $obj = $obj->UNBLESS; # Or is that already ->FREEZE >>> >>> Which perhaps would fall back on a core method that would just remove >>> the blessed flag if no "UNBLESS" sub was available. That way we could >>> generalize "as_hash" and other "remove private garbage and return >>> something sensible to reconstruct the object" which exists in almost >>> any non-trivial Perl program.
>> >> I was really not sure about this, but the more I thought about it, the more >> that something like this seems important to provide. It's also plausible that >> the right solution is that UNIVERSAL::UNBLESS just calls Scalar::Util::unbless, >> and now you have a toolkit. >> >> I haven't given it a lot of thought (yet?).
> > I am opposed to $obj->UNBLESS; Methods are overridable, and I would > consider a method call to "touch" the object, which could have any > sort of consequence. If we think we want this we should just add > unbless to the language like we have untie. IMO unbless should be > usable on something like Object::Deadly without triggering any method > calls. Also, I thing its weird to have a method call change the type > of its invocant like this, not entirely unheard of, but weird. > > Also unblessing is a strange thing given that the *referent* not the > reference is blessed, consider the action at a distance involved. One > part of the code might accept an object, validate that it has indeed > received an object, but then at some far distant point in the code the > object could be unblessed, leaving a non-object in memory, resulting > in strange consequences. Of course this also applies to *reblessing* > too, but still, we already have that problem, we dont "officially" > have the problem of unbless.
I should have added, that DDS, which is Object::Deadly proof, achieves the same result by blessing an object into a namespace known to have only "safe" methods. I did not need unbless to deal with Object::Deadly. Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"
Subject: Re: [perl #124428] bless $x, undef to unbless
Date: Thu, 30 Apr 2015 23:25:59 +0200
From: Aristotle Pagaltzis <pagaltzis [...] gmx.de>
CC: perlbug-followup [...] perl.org
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 4.1k
* Ed Avis <perlbug-followup@perl.org> [2015-04-30 15:40]: Show quoted text
> Sometimes you need to unbless a scalar. Various CPAN modules exist to > do this and various whimsical names such as 'curse' and 'smite', but > it deserves to be in the core language.
I’ve wished at various times that it existed, yes. Show quoted text
> No new keyword is needed; instead you should be able to just > > bless $x, undef; > > to unbless scalar $x. > > Note that this is not the same thing as > > bless $x; > > which should continue to bless into the current package.
Opposed. There is absolutely no advantage to shoe-horning this into `bless`. * Ævar Arnfjörð Bjarmason <avarab@gmail.com> [2015-04-30 16:30]: Show quoted text
> This makes more sense as a new function Scalar::Util or something.
Aye. * Ævar Arnfjörð Bjarmason <avarab@gmail.com> [2015-04-30 16:50]: Show quoted text
> We have tie() and untie(), not untying as some special parameter to > tie(), similarly for link() and unlink() or mkdir() and rmdir() for > that matter.
Good point. Show quoted text
> Also what should a function like this do? Objects are opaque and while > we can just remove the blessedness I think if the core introduced > something like this it would make more sense to make: > > unbless($obj); # or bless($obj, undef); .... > > Be: > > $obj = $obj->UNBLESS; # Or is that already ->FREEZE > > Which perhaps would fall back on a core method that would just remove > the blessed flag if no "UNBLESS" sub was available. That way we could > generalize "as_hash" and other "remove private garbage and return > something sensible to reconstruct the object" which exists in almost > any non-trivial Perl program. > > You could argue that it should do exactly nothing except remove the > blessed flag, but the absence of this feature in Perl now means people > don't expect their objects to go back to non-objects unless they > explicitly have some "object export" feature. A core API change like > this would have an effect on future code.
These issues are orthogonal. You are talking about the case in which encapsulation matters, i.e. I have some random object that I want to peel the blessedness off of. But there is just as legitimately the case where I have an object from a class I control, and I want an efficient way to get at its guts. Both are valid use cases with different requirements, so arguing against one based on the other is an instance of confusion, and choosing one of them as preferable would be a mistake. * Ed Avis <eda@waniasset.com> [2015-04-30 17:10]: Show quoted text
> An alternative proposal would be first to move Scalar::Util::blessed > into the core language, and then make it an lvalue. > > blessed($x) = 'Foo'; # blesses $x into package Foo > blessed($x) = undef; # unblesses $x > > But both this and C<bless $x, undef> work on a single scalar.
Again with the shoe-horning. Why would you want to? Show quoted text
> One advantage of adding 'unbless' is that it can work on a list: > > unbless @a; # unblesses each element > > As it happens that is the use case I am thinking of - and it is in > a hot path of my program, so if I could call a single builtin to deal > with the whole list that would be better than writing a loop. > > So on reflection I think adding 'unbless' may be the best way.
That is way low on the list of reasons to prefer a separate function, but sure, I can go with that. * Ed Avis <eda@waniasset.com> [2015-04-30 16:50]: Show quoted text
> unbless is already part of Data::Structure::Util (and other modules). > Although the implementation there is a bit funky in that it > recursively unblesses everything in the data structure - not what > I would have done :-( That does mean that the name 'unbless' is > already taken in some sense.
So having some random function called “unbless” in some random non-core never-heard-of-it-before CPAN module means the name and semantics are taken and set in stone… … whereas having had `bless $thing, undef` as part of the language and already having had a particular meaning forever and ever means it’s up for grabs? I don’t understand this conception of “taken”. (And similarly with `blessed`, though much less strongly.) Mauve regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/>
To: perl5-porters [...] perl.org
Date: Fri, 1 May 2015 07:23:51 +0000 (UTC)
Subject: Re: [perl #124428] bless $x, undef to unbless
From: Ed Avis <eda [...] waniasset.com>
Download (untitled) / with headers
text/plain 601b
C<bless $x, undef> produces two warnings if used. It is not documented in perlfunc (the single-arg case is, but not an explicit undef). To me, that suggests that the current behaviour is an implementation accident rather than a settled part of the language. The consensus seems to have converged on adding 'unbless' for other reasons, which is fine by me. If you think that C<bless $x, undef> is truly part of the language and should stay with its current semantics, I suggest documenting it in perlfunc and removing the two warnings which it currently produces. -- Ed Avis <eda@waniasset.com>
From: Zefram <zefram [...] fysh.org>
Subject: Re: [perl #124428] bless $x, undef to unbless
Date: Wed, 6 Dec 2017 03:33:41 +0000
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 532b
bless($x, undef) already has a defined meaning, and should not be changed. Its behaviour, including the warnings, arises naturally from the usual treatment of undef when a string is desired and from the behaviour of bless on an empty string. There is no need for specific documentation of this behaviour. The appropriate way to invoke unblessing is as a subroutine supplied by a module. As noted, this is already available. There is no need for the core to supply an unblessing facility. This ticket should be closed. -zefram
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 641b
Show quoted text
>bless($x, undef) already has a defined meaning,
Could this be made a bit more explicit in perlfunc, not just for undef, but for blessing into the empty string too? I would use some wording like If CLASSNAME is omitted, the current package is used. An empty string (or undef) for CLASSNAME is the same as 'main'. This is worth documenting since it's the one case where the string you get back from ref($x) is not the same as the string $s you passed to bless($x, $s). I would also add a note To unbless a scalar, see the Data::Structure::Util module on CPAN. either in the perlfunc section above, or somewhere in perlfaq.
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 171b
P.S. perhaps the note 'make sure that CLASSNAME is a true value' should also be revisited, given that bless($x, undef) has a defined meaning and undef is not a true value.
Subject: Re: [perl #124428] bless $x, undef to unbless
From: Zefram <zefram [...] fysh.org>
Date: Wed, 6 Dec 2017 17:28:39 +0000
To: perl5-porters [...] perl.org
Doc clarifications in commit b3893bfa90e8810497e2f81458a5a46db611cadf. -zefram
RT-Send-CC: perl5-porters [...] perl.org
Thanks for making the documentation changes.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org