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

func Class->method should resolve to func( Class->method ) #8874

Open
p5pRT opened this issue Apr 18, 2007 · 19 comments
Open

func Class->method should resolve to func( Class->method ) #8874

p5pRT opened this issue Apr 18, 2007 · 19 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 18, 2007

Migrated from rt.perl.org#42603 (status was 'open')

Searchable as RT42603$

@p5pRT
Copy link
Author

p5pRT commented Apr 18, 2007

From @schwern

Created by @schwern

  sub foo { 23 }
  sub Foo​::bar { 42 }
  foo Foo->bar

'Can't locate object method "foo" via package "Foo"'

Perl is trying to resolve that as Foo->foo->bar. However.

  sub foo { 23 }
  foo Foo->bar

'Can't locate object method "bar" via package "Foo"'

Perl is trying to resolve that as foo( Foo->bar ). The resolution
depends on whether Foo's symbol table has any entries. Very
ambiguous.

Perl can do a better job resolving that ambiguity. It could look
ahead two more characters and notice that the class name bareword is
followed by a ->. -> is the second highest precedence operator and
should bind tighter than indirect object syntax.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.8.8:

Configured by schwern at Sat Oct 14 18:47:46 PDT 2006.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=darwin, osvers=8.8.1, archname=darwin-thread-multi-2level
    uname='darwin windhund.local 8.8.1 darwin kernel version 8.8.1: mon sep 25 19:42:00 pdt 2006; root:xnu-792.13.8.obj~1release_i386 i386 i386 macbook1,1 darwin '
    config_args='-Dprefix=/usr/local/perl/5.8.8 -Duseithreads -Dccflags=-I/sw/include -Dldflags=-L/sw/lib -Dperladmin=schwern@pobox.com -Dcf_email=schwern@pobox.com -Dmyhostname=windhund -Dmydomain=.schwern.org -Dprivlib=/usr/local/perl/5.8.8/lib -Dsiteprefix=/usr/local -Dsitelib=/usr/local/lib/site_perl -Dlibpth=/usr/local/lib /sw/lib /opt/local/lib /usr/lib -Dnetdb_host_type=const char * -Dnetdb_hlen_type=socklen_t -Uinstallusrbinperl'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-I/sw/include -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/opt/local/include',
    optimize='-O3',
    cppflags='-no-cpp-precomp -I/sw/include -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/opt/local/include'
    ccversion='', gccversion='4.0.1 (Apple Computer, Inc. build 5363)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags ='-L/sw/lib -L/usr/local/lib -L/opt/local/lib'
    libpth=/usr/local/lib /sw/lib /opt/local/lib /usr/lib
    libs=-lgdbm -ldbm -ldl -lm -lc
    perllibs=-ldl -lm -lc
    libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-L/sw/lib -bundle -undefined dynamic_lookup -L/usr/local/lib -L/opt/local/lib'

Locally applied patches:
    


@INC for perl v5.8.8:
    /sw/lib/perl5
    /sw/lib/perl5/darwin
    /usr/local/perl/5.8.8/lib/darwin-thread-multi-2level
    /usr/local/perl/5.8.8/lib
    /usr/local/lib/site_perl/5.8/darwin-thread-multi-2level
    /usr/local/lib/site_perl
    /usr/local/lib/site_perl
    .


Environment for perl v5.8.8:
    DYLD_LIBRARY_PATH (unset)
    HOME=/Users/schwern
    LANG (unset)
    LANGUAGE (unset)
    LC_CTYPE=en_US.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/opt/local/bin:/opt/local/sbin:/sw/bin:/sw/sbin:/Users/schwern/bin:/usr/local/bin:/Users/schwern/bin:/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin
    PERL5LIB=/sw/lib/perl5:/sw/lib/perl5/darwin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Apr 19, 2007

From gerard@tty.nl

On Wed, Apr 18, 2007 at 09​:34​:22AM -0700, Michael G Schwern wrote​:

# New Ticket Created by Michael G Schwern
# Please include the string​: [perl #42603]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=42603 >

This is a bug report for perl from schwern@​pobox.com,
generated with the help of perlbug 1.35 running under perl v5.8.8.

-----------------------------------------------------------------
[Please enter your report here]

sub foo { 23 }
sub Foo​::bar { 42 }
foo Foo->bar

'Can't locate object method "foo" via package "Foo"'

Perl is trying to resolve that as Foo->foo->bar. However.

sub foo { 23 }
foo Foo->bar

'Can't locate object method "bar" via package "Foo"'

Perl is trying to resolve that as foo( Foo->bar ). The resolution
depends on whether Foo's symbol table has any entries. Very
ambiguous.

Perl can do a better job resolving that ambiguity. It could look
ahead two more characters and notice that the class name bareword is
followed by a ->. -> is the second highest precedence operator and
should bind tighter than indirect object syntax.

What I remember from removing indirect object syntax for kurila, is that
there were some modules (in the core) using the above syntax expecting
'foo Foo->bar' to resolve to Foo->foo->bar.
In your example the 'sub foo' exists, but if it doesn't
should 'foo Foo->bar' resolve to '(Foo->bar)->foo'?

Your solution only solves the problem for the -> operator, but that
would not solve the problem for all other operators (things like
'foo Foo or die'), although these give barewords errors at compile time when use strict is
enabled.

I agree that the ambiguity is very bad. It can lead to very nasty bugs
that depend on the load order of modules. That is also the primary
reason that I removed indirect object syntax in kurila.

But giving a warning when doing 'foo Foo->bar' doesn't sound bad, on
second thought, giving a warning when using any indirect object syntax
doesn't sound bad.

Gerard Goossen

ps. indirect object syntax also depends on whether foo is already
defined. From t/op/chr.t​:
  ok(opendir(H, "op"), "opendir op") or diag $!;
  ok(open(H, "<", "base"), "open base") or diag $!;
the diag does not really work as expected.

@p5pRT
Copy link
Author

p5pRT commented Apr 19, 2007

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @mauke

Created by @mauke

Let's create a dog and wash it​:

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash Dog->new;'
{;};
sub wash {
 
}
'Dog'->wash->new;
-e syntax OK

Wait, that's not what I meant! Maybe like this?

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash Dog​::->new;'
{;};
sub wash {
 
}
'Dog'->wash->new;
-e syntax OK

No, same problem. Hmm ...

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash :​:Dog->new;'
{;};
sub wash {
 
}
wash '​::Dog'->new;
-e syntax OK

OK, that at least parses the sub call correctly. But​:

% perl -e '{package Dog} sub wash {}' -e 'wash :​:Dog->new;'
Can't call method "new" without a package or object reference at -e line 2.

Looks like '​::Dog' doesn't work as 'Dog'. Finally​:

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash +Dog->new;'
{;};
sub wash {
 
}
wash 'Dog'->new;
-e syntax OK

This is what I wanted all along.

I think the indirect object heuristic is too trigger-happy and should be dialed
back a bit. 'foo bar->baz' should not be parsed as an indirect invocation of
'bar->foo', especially not if the parser knows 'foo' to be a sub in the current
scope.

In fact, I'd be glad to see indirect object syntax simply go away completely
(except for builtin special cases like print/system/exec/etc). Otherwise, a
pragma to disable it would be nice[1]. Otherwise, the parser should prefer the
non-indirect-object interpretation of code where possible.

[1]
'no indirect' is a nice pragma but it doesn't disable indirect object syntax;
it just recognizes it and makes it into an error after the fact. That is, the
default interpretation of my first example is silently wrong, 'no indirect'
makes it loudly wrong, and I want it to be silently right.

Perl Info

Flags:
    category=core
    severity=medium

This perlbug was built using Perl 5.12.1 - Thu Jun  3 20:09:15 CEST 2010
It is being executed now by  Perl 5.16.0 - Mon May 21 12:24:16 CEST 2012.

Site configuration information for perl 5.16.0:

Configured by mauke at Mon May 21 12:24:16 CEST 2012.

Summary of my perl5 (revision 5 version 16 subversion 0) configuration:
   
  Platform:
    osname=linux, osvers=2.6.38-gentoo-r6, archname=i686-linux
    uname='linux nora 2.6.38-gentoo-r6 #1 preempt sat aug 6 03:05:34 cest 2011 i686 amd athlon(tm) 64 processor 3200+ authenticamd gnulinux '
    config_args='-Dcc=cgcc -Dprefix=/home/mauke/usr/local -Dman1dir=none -Dman3dir=none -Dinc_version_list=none -Doptimize=-O2 -flto'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cgcc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -flto',
    cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.6.3', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cgcc', ldflags ='-fstack-protector -L/usr/local/lib -O2 -flto'
    libpth=/usr/local/lib /lib/../lib /usr/lib/../lib /lib /usr/lib
    libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.14.1.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.14.1'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -flto -L/usr/local/lib -fstack-protector'

Locally applied patches:
    SAVEARGV0 - disable magic open in <ARGV>


@INC for perl 5.16.0:
    /home/mauke/usr/local/lib/perl5/site_perl/5.16.0/i686-linux
    /home/mauke/usr/local/lib/perl5/site_perl/5.16.0
    /home/mauke/usr/local/lib/perl5/5.16.0/i686-linux
    /home/mauke/usr/local/lib/perl5/5.16.0
    .


Environment for perl 5.16.0:
    HOME=/home/mauke
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=POSIX
    LD_LIBRARY_PATH=/home/mauke/usr/local/lib
    LOGDIR (unset)
    PATH=/home/mauke/usr/perlbrew/bin:/home/mauke/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/4.4.5:/opt/sun-jdk-1.4.2.13/bin:/opt/sun-jdk-1.4.2.13/jre/bin:/opt/sun-jdk-1.4.2.13/jre/javaws:/opt/dmd/bin:/usr/games/bin
    PERLBREW_BASHRC_VERSION=0.43
    PERLBREW_HOME=/home/mauke/.perlbrew
    PERLBREW_PATH=/home/mauke/usr/perlbrew/bin
    PERLBREW_ROOT=/home/mauke/usr/perlbrew
    PERLBREW_VERSION=0.27
    PERL_BADLANG (unset)
    PERL_UNICODE=SAL
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @epa

via RT <l.mai <at> web.de> writes​:

In fact, I'd be glad to see indirect object syntax simply go away completely
(except for builtin special cases like print/system/exec/etc).

I think 'new' should be special-cased too.

--
Ed Avis <eda@​waniasset.com>

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From c.nehren/p5p@shadowcat.co.uk

On Tue, Aug 07, 2012 at 14​:18​:11 +0000 , Ed Avis wrote​:

via RT <l.mai <at> web.de> writes​:

In fact, I'd be glad to see indirect object syntax simply go away completely
(except for builtin special cases like print/system/exec/etc).

I think 'new' should be special-cased too.

Please no. This only exacerbates the problem of indirect object syntax
(which I agree should go away completely), sweeping the problem under
the rug and adding more complexity without solving the problem. It's a
net loss on all sides.

--
Chris Nehren | Coder, Sysadmin, Masochist
Shadowcat Systems Ltd. | http​://shadowcat.co.uk/

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @Leont

On Tue, Aug 7, 2012 at 4​:47 PM, l.mai@​web.de <perlbug-followup@​perl.org> wrote​:

I think the indirect object heuristic is too trigger-happy and should be dialed
back a bit. 'foo bar->baz' should not be parsed as an indirect invocation of
'bar->foo', especially not if the parser knows 'foo' to be a sub in the current
scope.

You're forgetting this scenario​: «new Foo->bar». I'd expect this to be
far more common, if only because this is how many other language
operate. IMHO changing it to do something subtle different is just a
lot of trouble for no benefit.

In fact, I'd be glad to see indirect object syntax simply go away completely
(except for builtin special cases like print/system/exec/etc). Otherwise, a
pragma to disable it would be nice[1]. Otherwise, the parser should prefer the
non-indirect-object interpretation of code where possible.

Everybody likes to hate indirect object syntax. I never use it, and
wouldn't mind it being gone it, but rarely get bitten by it.

Leon

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @Leont

On Tue, Aug 7, 2012 at 5​:21 PM, Chris Nehren
<c.nehren/p5p@​shadowcat.co.uk> wrote​:

On Tue, Aug 07, 2012 at 14​:18​:11 +0000 , Ed Avis wrote​:

via RT <l.mai <at> web.de> writes​:

In fact, I'd be glad to see indirect object syntax simply go away completely
(except for builtin special cases like print/system/exec/etc).

I think 'new' should be special-cased too.

Please no. This only exacerbates the problem of indirect object syntax
(which I agree should go away completely), sweeping the problem under
the rug and adding more complexity without solving the problem. It's a
net loss on all sides.

+1

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @epa

I wanted to make the point that if you intend to get rid of dative syntax,
perhaps 80% of the uses of it are for constructors, which by convention are
called 'new'. To simplify the grammar while avoiding as far as possible the
breakage of existing code, you could restrict the syntax to constructors.

If that's not an option, I would prefer to keep the indirect object syntax rather
than remove it altogether.

--
Ed Avis <eda@​waniasset.com>

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From c.nehren/p5p@shadowcat.co.uk

On Tue, Aug 07, 2012 at 15​:10​:14 +0000 , Ed Avis wrote​:

I wanted to make the point that if you intend to get rid of dative syntax,
perhaps 80% of the uses of it are for constructors, which by convention are
called 'new'. To simplify the grammar while avoiding as far as possible the
breakage of existing code, you could restrict the syntax to constructors.

I'm not sure I understand how adding a special case simplifies the
grammar. This only promotes 'new' to a position of specialness. Perl's
OO is as flexible as it is--it supports everything from inside-out
objects to Moose--because we provide mechanism, not policy. Making 'new'
special is providing policy, sharply in opposition to how things usually
work in Perl.

--
Chris Nehren | Coder, Sysadmin, Masochist
Shadowcat Systems Ltd. | http​://shadowcat.co.uk/

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @xdg

On Tue, Aug 7, 2012 at 9​:47 AM, l.mai@​web.de <perlbug-followup@​perl.org> wrote​:

In fact, I'd be glad to see indirect object syntax simply go away completely
(except for builtin special cases like print/system/exec/etc). Otherwise, a
pragma to disable it would be nice[1]. Otherwise, the parser should prefer the
non-indirect-object interpretation of code where possible.

+1

My preference​: indirect object syntax (except for built-in special
cases) gets deprecated under "use v5.18" and then removed under "use
v5.18+N" where N is whatever our deprecation policy turns out to be.

-- David

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @Abigail

On Tue, Aug 07, 2012 at 03​:10​:14PM +0000, Ed Avis wrote​:

I wanted to make the point that if you intend to get rid of dative syntax,
perhaps 80% of the uses of it are for constructors, which by convention are
called 'new'. To simplify the grammar while avoiding as far as possible the
breakage of existing code, you could restrict the syntax to constructors.

If that's not an option, I would prefer to keep the indirect object syntax rather
than remove it altogether.

Perl already has a constructor, it's special cased (as in, it's a keyword),
and it's spelled "bless".

Abigail

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2012

From @Abigail

On Tue, Aug 07, 2012 at 06​:47​:50AM -0700, l.mai@​web.de wrote​:

# New Ticket Created by l.mai@​web.de
# Please include the string​: [perl #114414]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=114414 >

This is a bug report for perl from l.mai@​web.de,
generated with the help of perlbug 1.39 running under perl 5.16.0.

-----------------------------------------------------------------
[Please describe your issue here]

Let's create a dog and wash it​:

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash Dog->new;'
{;};
sub wash {

}
'Dog'->wash->new;
-e syntax OK

Wait, that's not what I meant! Maybe like this?

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash Dog​::->new;'
{;};
sub wash {

}
'Dog'->wash->new;
-e syntax OK

No, same problem. Hmm ...

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash :​:Dog->new;'
{;};
sub wash {

}
wash '​::Dog'->new;
-e syntax OK

OK, that at least parses the sub call correctly. But​:

% perl -e '{package Dog} sub wash {}' -e 'wash :​:Dog->new;'
Can't call method "new" without a package or object reference at -e line 2.

Looks like '​::Dog' doesn't work as 'Dog'. Finally​:

% perl -MO=Deparse -e '{package Dog} sub wash {}' -e 'wash +Dog->new;'
{;};
sub wash {

}
wash 'Dog'->new;
-e syntax OK

This is what I wanted all along.

I think the indirect object heuristic is too trigger-happy and should be dialed
back a bit. 'foo bar->baz' should not be parsed as an indirect invocation of
'bar->foo', especially not if the parser knows 'foo' to be a sub in the current
scope.

In fact, I'd be glad to see indirect object syntax simply go away completely
(except for builtin special cases like print/system/exec/etc). Otherwise, a
pragma to disable it would be nice[1]. Otherwise, the parser should prefer the
non-indirect-object interpretation of code where possible.

[1]
'no indirect' is a nice pragma but it doesn't disable indirect object syntax;
it just recognizes it and makes it into an error after the fact. That is, the
default interpretation of my first example is silently wrong, 'no indirect'
makes it loudly wrong, and I want it to be silently right.

Is this indirect object heuristic, or bare word heuristics?

  $ perl -MO=Deparse -e '{package Dog} sub wash {} wash "Dog" -> new'
  {;};
  sub wash {
 
  }
  wash 'Dog'->new;
  -e syntax OK
  $

If you don't want to get bitten by Perl having to guess what you mean,
one could also just quote their barewords.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Nov 14, 2017

From zefram@fysh.org

Tinkering with the rules for indirect object syntax would be foolish.

Any change to the ambiguity resolution in the absence of new pragmata
would break existing working code and make it more difficult to write
code that's portable across Perl versions. Backcompat requirements
mean we really can't change the default rules at all, other than via a
deprecation cycle.

If we were to introduce a new pragma, that could invoke a different
set of rules for indirect object syntax without backcompat trouble.
However, if the alternate rules are merely different, that doesn't really
solve anything. It would handle some cases in an arguably better way,
but it would still be a set of heuristics, still liable to surprise,
and probably still impossible for a human to learn. It's not worth
introducing a pragma for such a weak effect.

The only pragma here that would be worth introducing would be one that
disables indirect object syntax entirely. Abolish, don't tinker. In the
scope of the pragma, things that look like they could be indirect object
syntax would be resolved as other syntax if possible, and would be syntax
errors if not. I think this can be done without great difficulty, but
I wonder whether there are lurking ambiguities that this wouldn't resolve.

I think the new pragma should be a "feature" subpragma. I'm in two
minds as to whether the positive form of the pragma should refer to
suppression or to presence of indirect object syntax.

I'm also not sure whether "print {$fh} $stuff" should count as indirect
object syntax for the purposes of the pragma. Unlike the way indirect
object syntax applies to ordinary method calls, this is the only syntax
that will produce the optree that it produces. I'm not sure how closely
related the two kinds of indirect object syntax are internally.

If there are no objections, I'd like to go ahead with implementing some
form of this feature.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 14, 2017

From @cpansprout

On Tue, 14 Nov 2017 05​:47​:21 -0800, zefram@​fysh.org wrote​:

I'm also not sure whether "print {$fh} $stuff" should count as indirect
object syntax for the purposes of the pragma. Unlike the way indirect
object syntax applies to ordinary method calls, this is the only syntax
that will produce the optree that it produces.

Likewise, SUPER​::foo{@​_} is the only syntax that will produce the optree that it produces. That is a very useful feature, which I use frequently, despite the fact that its documentation was deleted when perlobj was rewritten.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Nov 14, 2017

From @schwern

On Tue, 14 Nov 2017 05​:47​:21 -0800, zefram@​fysh.org wrote​:

The only pragma here that would be worth introducing would be one that
disables indirect object syntax entirely. Abolish, don't tinker. In the
scope of the pragma, things that look like they could be indirect object
syntax would be resolved as other syntax if possible, and would be syntax
errors if not. I think this can be done without great difficulty, but
I wonder whether there are lurking ambiguities that this wouldn't resolve.

Yes. I concur. Wholeheartedly and with no reservations. Give us a pragma to turn off indirect object syntax.

I think the new pragma should be a "feature" subpragma. I'm in two
minds as to whether the positive form of the pragma should refer to
suppression or to presence of indirect object syntax.

There is already indirect.pm which is used as `no indirect`.
https://metacpan.org/pod/indirect

I'd say make `indirect` a feature, on by default, and turn it off with `no feature "indirect"`. I'm sure I can think of a few more existing features I'd like to have pragmas to turn off.

I'm also not sure whether "print {$fh} $stuff" should count as indirect
object syntax for the purposes of the pragma. Unlike the way indirect
object syntax applies to ordinary method calls, this is the only syntax
that will produce the optree that it produces. I'm not sure how closely
related the two kinds of indirect object syntax are internally.

My inclination is to deal with special cases like `print` and `open` separately. They're their own hairballs. But I haven't given it much thought.

@p5pRT
Copy link
Author

p5pRT commented Nov 15, 2017

From @Smylers

Father Chrysostomos via RT writes​:

On Tue, 14 Nov 2017 05​:47​:21 -0800, zefram@​fysh.org wrote​:

I'm also not sure whether "print {$fh} $stuff" should count as
indirect object syntax for the purposes of the pragma. Unlike the
way indirect object syntax applies to ordinary method calls, this is
the only syntax that will produce the optree that it produces.

Likewise, SUPER​::foo{@​_} is the only syntax that will produce the
optree that it produces. That is a very useful feature, which I use
frequently,

What's it do? I couldn't find any instances of it on Cpan​:
https://grep.metacpan.org/search?q=SUPER%3A%3A\w%2B\s*\{&qd=&qft=*.pm

It looks like using braces to denote the invocant, so would be
equivalent to​:

  my $object = do { @​_ };
  $object->SUPER​::foo;

but that sets $object to the number of elements in @​_ ... so I can't be
right about that.

despite the fact that its documentation was deleted when perlobj was
rewritten.

Are you referring to 7168b25, ‘Lots of revisions from Damian for
perlobj’ in 2011? That mentioned that being able to use braces with
indirect object notation, with the example of​:

  move {$obj->{FIELD}};

being equivalent to​:

  $obj->{FIELD}->move();

Is there any reason not to restore mention of this syntax to the
documentation?

Smylers

@p5pRT
Copy link
Author

p5pRT commented Nov 15, 2017

From zefram@fysh.org

Smylers wrote​:

What's it do?

It puts the elements of @​_ on the stack, uses the first of them as the
invocant, and calls the method on that invocant with the rest of the
elements as arguments. It behaves just like "shift->SUPER​::foo(@​_)",
except that it doesn't shift the invocant off @​_. It's pretty weird​:
it works because the braced block is in list context, whereas one would
expect the invocant to be evaluated in scalar context (which it is for
direct object syntax). It's almost certainly accidental, and arguably
a bug, though one to be cautious about fixing.

-zefram

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