Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stringify overload called too soon? #11705

Open
p5pRT opened this issue Oct 18, 2011 · 1 comment
Open

Stringify overload called too soon? #11705

p5pRT opened this issue Oct 18, 2011 · 1 comment

Comments

@p5pRT
Copy link

p5pRT commented Oct 18, 2011

Migrated from rt.perl.org#101640 (status was 'new')

Searchable as RT101640$

@p5pRT
Copy link
Author

p5pRT commented Oct 18, 2011

From ben@morrow.me.uk

Created by ben@morrow.me.uk

If I have a class with both stringify and concat overloading, where
concat returns a new object, like this​:

  package DeferConcat;

  use overload q/""/ => "force", q/./ => "concat";

  sub new { bless [$_[1]] }
  sub force { join "", @​{$_[0]} }
  sub concat { bless [@​{$_[0]}, $_[1]] }

then interpolating one of these objects into a string and assigning it
to a lexical stringifies it all the way out to a plain string, rather
than returning the object from concat​:

  my $o = DeferConcat->new("foo");
  my $x; # $x needs to be already declared
  $x = "A $o B"; # $x is now *not* an object

This may not seem surprising, but in every other case perl just calls
concat overloading without stringifying, which for what I'm trying to do
is more useful. In particular, all of these give you an object​:

  my $x = "A $o B"; # assign with LVINTRO
  $x = "A $o"; # interpolation with only two pieces
  $x = "" . "A $o B"; # random extra concatenation
  our $y; $y = "A $o B";
  my $h; $h{x} = "A $o B";

and indeed ref("A $o B") shows the bare expression is an object.

If this is a bug, then it comes from this bit of op.c (l9826 in blead)

  case OP_CONCAT​:
  if (o->op_next && o->op_next->op_type == OP_STRINGIFY) {
  if (o->op_next->op_private & OPpTARGET_MY) {
  if (o->op_flags & OPf_STACKED) /* chained concats */
  break; /* ignore_optimization */
  else {
  /* steal the OP_STRINGIFY's targ */

where that 'break' causes the stringify not to get optimized away. I'm
not sure what the best way to fix it would be​: the least intrusive would
be to give OP_STRINGIFY a private flag saying 'don't stringify at all,
just assign to your TARG', but it seems a bit odd to leave a stringify
op that doesn't actually stringify anything.

Ben

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.15.3:

Configured by mauzo at Tue Oct 18 18:35:52 BST 2011.

Summary of my perl5 (revision 5 version 15 subversion 3) configuration:
  Commit id: 05f861a2cb5b8f36d571c879ab8b15dd52a612f7
  Platform:
    osname=freebsd, osvers=8.2-release-p2, archname=amd64-freebsd
    uname='freebsd anubis.morrow.me.uk 8.2-release-p2 freebsd 8.2-release-p2 #7: thu jun 9 14:58:42 bst 2011 mauzo@anubis:usrobjusrsrcsysanubis amd64 '
    config_args='-des -Dusedevel -Dprefix=/opt/blead -Uinstallusrbinperl'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include',
    optimize='-O',
    cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.2.1 20070719  [FreeBSD]', 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='cc', ldflags ='-Wl,-E  -fstack-protector -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib
    libs=-lgdbm -lm -lcrypt -lutil -lc
    perllibs=-lm -lcrypt -lutil -lc
    libc=, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib -fstack-protector'

Locally applied patches:
    


@INC for perl 5.15.3:
    /opt/blead/lib/perl5/site_perl/5.15.3/amd64-freebsd
    /opt/blead/lib/perl5/site_perl/5.15.3
    /opt/blead/lib/perl5/5.15.3/amd64-freebsd
    /opt/blead/lib/perl5/5.15.3
    .


Environment for perl 5.15.3:
    HOME=/home/mauzo
    LANG (unset)
    LANGUAGE (unset)
    LC_ALL=en_GB.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/opt/blead/bin:/usr/local/libexec/ccache:/opt/tex/bin/amd64-freebsd:/usr/local/libexec/ccache:/opt/tex/bin/amd64-freebsd:/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/home/mauzo/bin
    PERLDOC_PAGER=vlm
    PERL_BADLANG (unset)
    SHELL=/usr/local/bin/mksh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants