Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 527 forks source link

[PATCH] __SUB__ #10897

Closed p5pRT closed 12 years ago

p5pRT commented 13 years ago

Migrated from rt.perl.org#80628 (status was 'resolved')

Searchable as RT80628$

p5pRT commented 13 years ago

From @cpansprout

This patch adds a __SUB__ keyword that returns the current subroutine\, or undef for the main program\, a special block\, or an eval.

If there are no objections\, I will add docs and push this shortly before 5.13.8.

I first thought of adding this to make recursive lexicals subs easier to write (whenever they are added)​:

my sub foo { __SUB__->() }

my sub foo; # the alternative my sub foo { foo() }

The really neat thing\, which I realised only after writing it\, is that it allows for recursive closures to be written much more simply​:

sub make_recursive_function {   my $arg = shift;   sub {   print "$_[0]\n";   __SUB__->($_[0] + 1) if $_[0] \< $arg;   } }

as opposed to​:

use Scalar​::Util; sub make_recursive_function {   my $arg = shift;   my $sub;   my $life_raft = $sub = sub {   print "$_[0]\n";   &$sub($_[0] + 1) if $_[0] \< $arg;   }   Scalar​::Util​::weaken($sub);   $sub; }

[Reminder to myself​: I need to add it to Opcode.pm as well.]


Flags​:   category=core   severity=wishlist


Site configuration information for perl 5.13.7​:

Configured by sprout at Thu Dec 9 14​:53​:58 PST 2010.

Summary of my perl5 (revision 5 version 13 subversion 7) configuration​:   Snapshot of​: 9e9fdd5de1676d607ddf9b9f10b8df2659af3ded   Platform​:   osname=darwin\, osvers=10.4.0\, archname=darwin-2level   uname='darwin pint.local 10.4.0 darwin kernel version 10.4.0​: fri apr 23 18​:28​:53 pdt 2010; root​:xnu-1504.7.4~1release_i386 i386 '   config_args='-de -Dusedevel -DDEBUGGING'   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='cc'\, ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'\,   optimize='-O3 -g'\,   cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'   ccversion=''\, gccversion='4.2.1 (Apple Inc. build 5664)'\, 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 =' -fstack-protector -L/usr/local/lib'   libpth=/usr/local/lib /usr/lib   libs=-ldbm -ldl -lm -lutil -lc   perllibs=-ldl -lm -lutil -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=' -bundle -undefined dynamic_lookup -L/usr/local/lib -fstack-protector'

Locally applied patches​:  


@​INC for perl 5.13.7​:   /usr/local/lib/perl5/site_perl/5.13.7/darwin-2level   /usr/local/lib/perl5/site_perl/5.13.7   /usr/local/lib/perl5/5.13.7/darwin-2level   /usr/local/lib/perl5/5.13.7   /usr/local/lib/perl5/site_perl   .


Environment for perl 5.13.7​:   DYLD_LIBRARY_PATH (unset)   HOME=/Users/sprout   LANG=en_US.UTF-8   LANGUAGE (unset)   LD_LIBRARY_PATH (unset)   LOGDIR (unset)   PATH=/usr/bin​:/bin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/X11/bin​:/usr/local/bin   PERL_BADLANG (unset)   SHELL=/bin/bash

p5pRT commented 13 years ago

From @cpansprout

Inline Patch ```diff diff --git a/embed.h b/embed.h index 5f846f5..f511965 100644 --- a/embed.h +++ b/embed.h @@ -1363,6 +1363,7 @@ #define pp_rindex() Perl_pp_rindex(aTHX) #define pp_rkeys() Perl_pp_rkeys(aTHX) #define pp_rmdir() Perl_pp_rmdir(aTHX) +#define pp_runcv() Perl_pp_runcv(aTHX) #define pp_rv2av() Perl_pp_rv2av(aTHX) #define pp_rv2cv() Perl_pp_rv2cv(aTHX) #define pp_rv2gv() Perl_pp_rv2gv(aTHX) diff --git a/keywords.h b/keywords.h index 526f3e4..1f63f06 100644 --- a/keywords.h +++ b/keywords.h @@ -16,254 +16,255 @@ #define KEY___FILE__ 1 #define KEY___LINE__ 2 #define KEY___PACKAGE__ 3 -#define KEY___DATA__ 4 -#define KEY___END__ 5 -#define KEY_AUTOLOAD 6 -#define KEY_BEGIN 7 -#define KEY_UNITCHECK 8 -#define KEY_CORE 9 -#define KEY_DESTROY 10 -#define KEY_END 11 -#define KEY_INIT 12 -#define KEY_CHECK 13 -#define KEY_abs 14 -#define KEY_accept 15 -#define KEY_alarm 16 -#define KEY_and 17 -#define KEY_atan2 18 -#define KEY_bind 19 -#define KEY_binmode 20 -#define KEY_bless 21 -#define KEY_break 22 -#define KEY_caller 23 -#define KEY_chdir 24 -#define KEY_chmod 25 -#define KEY_chomp 26 -#define KEY_chop 27 -#define KEY_chown 28 -#define KEY_chr 29 -#define KEY_chroot 30 -#define KEY_close 31 -#define KEY_closedir 32 -#define KEY_cmp 33 -#define KEY_connect 34 -#define KEY_continue 35 -#define KEY_cos 36 -#define KEY_crypt 37 -#define KEY_dbmclose 38 -#define KEY_dbmopen 39 -#define KEY_default 40 -#define KEY_defined 41 -#define KEY_delete 42 -#define KEY_die 43 -#define KEY_do 44 -#define KEY_dump 45 -#define KEY_each 46 -#define KEY_else 47 -#define KEY_elsif 48 -#define KEY_endgrent 49 -#define KEY_endhostent 50 -#define KEY_endnetent 51 -#define KEY_endprotoent 52 -#define KEY_endpwent 53 -#define KEY_endservent 54 -#define KEY_eof 55 -#define KEY_eq 56 -#define KEY_eval 57 -#define KEY_exec 58 -#define KEY_exists 59 -#define KEY_exit 60 -#define KEY_exp 61 -#define KEY_fcntl 62 -#define KEY_fileno 63 -#define KEY_flock 64 -#define KEY_for 65 -#define KEY_foreach 66 -#define KEY_fork 67 -#define KEY_format 68 -#define KEY_formline 69 -#define KEY_ge 70 -#define KEY_getc 71 -#define KEY_getgrent 72 -#define KEY_getgrgid 73 -#define KEY_getgrnam 74 -#define KEY_gethostbyaddr 75 -#define KEY_gethostbyname 76 -#define KEY_gethostent 77 -#define KEY_getlogin 78 -#define KEY_getnetbyaddr 79 -#define KEY_getnetbyname 80 -#define KEY_getnetent 81 -#define KEY_getpeername 82 -#define KEY_getpgrp 83 -#define KEY_getppid 84 -#define KEY_getpriority 85 -#define KEY_getprotobyname 86 -#define KEY_getprotobynumber 87 -#define KEY_getprotoent 88 -#define KEY_getpwent 89 -#define KEY_getpwnam 90 -#define KEY_getpwuid 91 -#define KEY_getservbyname 92 -#define KEY_getservbyport 93 -#define KEY_getservent 94 -#define KEY_getsockname 95 -#define KEY_getsockopt 96 -#define KEY_given 97 -#define KEY_glob 98 -#define KEY_gmtime 99 -#define KEY_goto 100 -#define KEY_grep 101 -#define KEY_gt 102 -#define KEY_hex 103 -#define KEY_if 104 -#define KEY_index 105 -#define KEY_int 106 -#define KEY_ioctl 107 -#define KEY_join 108 -#define KEY_keys 109 -#define KEY_kill 110 -#define KEY_last 111 -#define KEY_lc 112 -#define KEY_lcfirst 113 -#define KEY_le 114 -#define KEY_length 115 -#define KEY_link 116 -#define KEY_listen 117 -#define KEY_local 118 -#define KEY_localtime 119 -#define KEY_lock 120 -#define KEY_log 121 -#define KEY_lstat 122 -#define KEY_lt 123 -#define KEY_m 124 -#define KEY_map 125 -#define KEY_mkdir 126 -#define KEY_msgctl 127 -#define KEY_msgget 128 -#define KEY_msgrcv 129 -#define KEY_msgsnd 130 -#define KEY_my 131 -#define KEY_ne 132 -#define KEY_next 133 -#define KEY_no 134 -#define KEY_not 135 -#define KEY_oct 136 -#define KEY_open 137 -#define KEY_opendir 138 -#define KEY_or 139 -#define KEY_ord 140 -#define KEY_our 141 -#define KEY_pack 142 -#define KEY_package 143 -#define KEY_pipe 144 -#define KEY_pop 145 -#define KEY_pos 146 -#define KEY_print 147 -#define KEY_printf 148 -#define KEY_prototype 149 -#define KEY_push 150 -#define KEY_q 151 -#define KEY_qq 152 -#define KEY_qr 153 -#define KEY_quotemeta 154 -#define KEY_qw 155 -#define KEY_qx 156 -#define KEY_rand 157 -#define KEY_read 158 -#define KEY_readdir 159 -#define KEY_readline 160 -#define KEY_readlink 161 -#define KEY_readpipe 162 -#define KEY_recv 163 -#define KEY_redo 164 -#define KEY_ref 165 -#define KEY_rename 166 -#define KEY_require 167 -#define KEY_reset 168 -#define KEY_return 169 -#define KEY_reverse 170 -#define KEY_rewinddir 171 -#define KEY_rindex 172 -#define KEY_rmdir 173 -#define KEY_s 174 -#define KEY_say 175 -#define KEY_scalar 176 -#define KEY_seek 177 -#define KEY_seekdir 178 -#define KEY_select 179 -#define KEY_semctl 180 -#define KEY_semget 181 -#define KEY_semop 182 -#define KEY_send 183 -#define KEY_setgrent 184 -#define KEY_sethostent 185 -#define KEY_setnetent 186 -#define KEY_setpgrp 187 -#define KEY_setpriority 188 -#define KEY_setprotoent 189 -#define KEY_setpwent 190 -#define KEY_setservent 191 -#define KEY_setsockopt 192 -#define KEY_shift 193 -#define KEY_shmctl 194 -#define KEY_shmget 195 -#define KEY_shmread 196 -#define KEY_shmwrite 197 -#define KEY_shutdown 198 -#define KEY_sin 199 -#define KEY_sleep 200 -#define KEY_socket 201 -#define KEY_socketpair 202 -#define KEY_sort 203 -#define KEY_splice 204 -#define KEY_split 205 -#define KEY_sprintf 206 -#define KEY_sqrt 207 -#define KEY_srand 208 -#define KEY_stat 209 -#define KEY_state 210 -#define KEY_study 211 -#define KEY_sub 212 -#define KEY_substr 213 -#define KEY_symlink 214 -#define KEY_syscall 215 -#define KEY_sysopen 216 -#define KEY_sysread 217 -#define KEY_sysseek 218 -#define KEY_system 219 -#define KEY_syswrite 220 -#define KEY_tell 221 -#define KEY_telldir 222 -#define KEY_tie 223 -#define KEY_tied 224 -#define KEY_time 225 -#define KEY_times 226 -#define KEY_tr 227 -#define KEY_truncate 228 -#define KEY_uc 229 -#define KEY_ucfirst 230 -#define KEY_umask 231 -#define KEY_undef 232 -#define KEY_unless 233 -#define KEY_unlink 234 -#define KEY_unpack 235 -#define KEY_unshift 236 -#define KEY_untie 237 -#define KEY_until 238 -#define KEY_use 239 -#define KEY_utime 240 -#define KEY_values 241 -#define KEY_vec 242 -#define KEY_wait 243 -#define KEY_waitpid 244 -#define KEY_wantarray 245 -#define KEY_warn 246 -#define KEY_when 247 -#define KEY_while 248 -#define KEY_write 249 -#define KEY_x 250 -#define KEY_xor 251 -#define KEY_y 252 +#define KEY___SUB__ 4 +#define KEY___DATA__ 5 +#define KEY___END__ 6 +#define KEY_AUTOLOAD 7 +#define KEY_BEGIN 8 +#define KEY_UNITCHECK 9 +#define KEY_CORE 10 +#define KEY_DESTROY 11 +#define KEY_END 12 +#define KEY_INIT 13 +#define KEY_CHECK 14 +#define KEY_abs 15 +#define KEY_accept 16 +#define KEY_alarm 17 +#define KEY_and 18 +#define KEY_atan2 19 +#define KEY_bind 20 +#define KEY_binmode 21 +#define KEY_bless 22 +#define KEY_break 23 +#define KEY_caller 24 +#define KEY_chdir 25 +#define KEY_chmod 26 +#define KEY_chomp 27 +#define KEY_chop 28 +#define KEY_chown 29 +#define KEY_chr 30 +#define KEY_chroot 31 +#define KEY_close 32 +#define KEY_closedir 33 +#define KEY_cmp 34 +#define KEY_connect 35 +#define KEY_continue 36 +#define KEY_cos 37 +#define KEY_crypt 38 +#define KEY_dbmclose 39 +#define KEY_dbmopen 40 +#define KEY_default 41 +#define KEY_defined 42 +#define KEY_delete 43 +#define KEY_die 44 +#define KEY_do 45 +#define KEY_dump 46 +#define KEY_each 47 +#define KEY_else 48 +#define KEY_elsif 49 +#define KEY_endgrent 50 +#define KEY_endhostent 51 +#define KEY_endnetent 52 +#define KEY_endprotoent 53 +#define KEY_endpwent 54 +#define KEY_endservent 55 +#define KEY_eof 56 +#define KEY_eq 57 +#define KEY_eval 58 +#define KEY_exec 59 +#define KEY_exists 60 +#define KEY_exit 61 +#define KEY_exp 62 +#define KEY_fcntl 63 +#define KEY_fileno 64 +#define KEY_flock 65 +#define KEY_for 66 +#define KEY_foreach 67 +#define KEY_fork 68 +#define KEY_format 69 +#define KEY_formline 70 +#define KEY_ge 71 +#define KEY_getc 72 +#define KEY_getgrent 73 +#define KEY_getgrgid 74 +#define KEY_getgrnam 75 +#define KEY_gethostbyaddr 76 +#define KEY_gethostbyname 77 +#define KEY_gethostent 78 +#define KEY_getlogin 79 +#define KEY_getnetbyaddr 80 +#define KEY_getnetbyname 81 +#define KEY_getnetent 82 +#define KEY_getpeername 83 +#define KEY_getpgrp 84 +#define KEY_getppid 85 +#define KEY_getpriority 86 +#define KEY_getprotobyname 87 +#define KEY_getprotobynumber 88 +#define KEY_getprotoent 89 +#define KEY_getpwent 90 +#define KEY_getpwnam 91 +#define KEY_getpwuid 92 +#define KEY_getservbyname 93 +#define KEY_getservbyport 94 +#define KEY_getservent 95 +#define KEY_getsockname 96 +#define KEY_getsockopt 97 +#define KEY_given 98 +#define KEY_glob 99 +#define KEY_gmtime 100 +#define KEY_goto 101 +#define KEY_grep 102 +#define KEY_gt 103 +#define KEY_hex 104 +#define KEY_if 105 +#define KEY_index 106 +#define KEY_int 107 +#define KEY_ioctl 108 +#define KEY_join 109 +#define KEY_keys 110 +#define KEY_kill 111 +#define KEY_last 112 +#define KEY_lc 113 +#define KEY_lcfirst 114 +#define KEY_le 115 +#define KEY_length 116 +#define KEY_link 117 +#define KEY_listen 118 +#define KEY_local 119 +#define KEY_localtime 120 +#define KEY_lock 121 +#define KEY_log 122 +#define KEY_lstat 123 +#define KEY_lt 124 +#define KEY_m 125 +#define KEY_map 126 +#define KEY_mkdir 127 +#define KEY_msgctl 128 +#define KEY_msgget 129 +#define KEY_msgrcv 130 +#define KEY_msgsnd 131 +#define KEY_my 132 +#define KEY_ne 133 +#define KEY_next 134 +#define KEY_no 135 +#define KEY_not 136 +#define KEY_oct 137 +#define KEY_open 138 +#define KEY_opendir 139 +#define KEY_or 140 +#define KEY_ord 141 +#define KEY_our 142 +#define KEY_pack 143 +#define KEY_package 144 +#define KEY_pipe 145 +#define KEY_pop 146 +#define KEY_pos 147 +#define KEY_print 148 +#define KEY_printf 149 +#define KEY_prototype 150 +#define KEY_push 151 +#define KEY_q 152 +#define KEY_qq 153 +#define KEY_qr 154 +#define KEY_quotemeta 155 +#define KEY_qw 156 +#define KEY_qx 157 +#define KEY_rand 158 +#define KEY_read 159 +#define KEY_readdir 160 +#define KEY_readline 161 +#define KEY_readlink 162 +#define KEY_readpipe 163 +#define KEY_recv 164 +#define KEY_redo 165 +#define KEY_ref 166 +#define KEY_rename 167 +#define KEY_require 168 +#define KEY_reset 169 +#define KEY_return 170 +#define KEY_reverse 171 +#define KEY_rewinddir 172 +#define KEY_rindex 173 +#define KEY_rmdir 174 +#define KEY_s 175 +#define KEY_say 176 +#define KEY_scalar 177 +#define KEY_seek 178 +#define KEY_seekdir 179 +#define KEY_select 180 +#define KEY_semctl 181 +#define KEY_semget 182 +#define KEY_semop 183 +#define KEY_send 184 +#define KEY_setgrent 185 +#define KEY_sethostent 186 +#define KEY_setnetent 187 +#define KEY_setpgrp 188 +#define KEY_setpriority 189 +#define KEY_setprotoent 190 +#define KEY_setpwent 191 +#define KEY_setservent 192 +#define KEY_setsockopt 193 +#define KEY_shift 194 +#define KEY_shmctl 195 +#define KEY_shmget 196 +#define KEY_shmread 197 +#define KEY_shmwrite 198 +#define KEY_shutdown 199 +#define KEY_sin 200 +#define KEY_sleep 201 +#define KEY_socket 202 +#define KEY_socketpair 203 +#define KEY_sort 204 +#define KEY_splice 205 +#define KEY_split 206 +#define KEY_sprintf 207 +#define KEY_sqrt 208 +#define KEY_srand 209 +#define KEY_stat 210 +#define KEY_state 211 +#define KEY_study 212 +#define KEY_sub 213 +#define KEY_substr 214 +#define KEY_symlink 215 +#define KEY_syscall 216 +#define KEY_sysopen 217 +#define KEY_sysread 218 +#define KEY_sysseek 219 +#define KEY_system 220 +#define KEY_syswrite 221 +#define KEY_tell 222 +#define KEY_telldir 223 +#define KEY_tie 224 +#define KEY_tied 225 +#define KEY_time 226 +#define KEY_times 227 +#define KEY_tr 228 +#define KEY_truncate 229 +#define KEY_uc 230 +#define KEY_ucfirst 231 +#define KEY_umask 232 +#define KEY_undef 233 +#define KEY_unless 234 +#define KEY_unlink 235 +#define KEY_unpack 236 +#define KEY_unshift 237 +#define KEY_untie 238 +#define KEY_until 239 +#define KEY_use 240 +#define KEY_utime 241 +#define KEY_values 242 +#define KEY_vec 243 +#define KEY_wait 244 +#define KEY_waitpid 245 +#define KEY_wantarray 246 +#define KEY_warn 247 +#define KEY_when 248 +#define KEY_while 249 +#define KEY_write 250 +#define KEY_x 251 +#define KEY_xor 252 +#define KEY_y 253 /* ex: set ro: */ diff --git a/opcode.h b/opcode.h index 122c67f..0a9f94d 100644 --- a/opcode.h +++ b/opcode.h @@ -398,6 +398,7 @@ EXTCONST char* const PL_op_name[] = { "rkeys", "rvalues", "transr", + "runcv", }; #endif @@ -775,6 +776,7 @@ EXTCONST char* const PL_op_desc[] = { "keys on reference", "values on reference", "transliteration (tr///)", + "__SUB__", }; #endif @@ -1166,6 +1168,7 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */ Perl_pp_rkeys, Perl_pp_rkeys, /* Perl_pp_rvalues */ Perl_pp_trans, /* Perl_pp_transr */ + Perl_pp_runcv, } #endif #ifdef PERL_PPADDR_INITED @@ -1554,6 +1557,7 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */ Perl_ck_each, /* rkeys */ Perl_ck_each, /* rvalues */ Perl_ck_match, /* transr */ + Perl_ck_null, /* runcv */ } #endif #ifdef PERL_CHECK_INITED @@ -1936,6 +1940,7 @@ EXTCONST U32 PL_opargs[] = { 0x00001b08, /* rkeys */ 0x00001b08, /* rvalues */ 0x00001804, /* transr */ + 0x00000004, /* runcv */ }; #endif diff --git a/opnames.h b/opnames.h index 609c6e2..3e14f30 100644 --- a/opnames.h +++ b/opnames.h @@ -385,10 +385,11 @@ typedef enum opcode { OP_RKEYS = 367, OP_RVALUES = 368, OP_TRANSR = 369, + OP_RUNCV = 370, OP_max } opcode; -#define MAXO 370 +#define MAXO 371 #define OP_phoney_INPUT_ONLY -1 #define OP_phoney_OUTPUT_ONLY -2 diff --git a/perl_keyword.pl b/perl_keyword.pl index 73128c3..9bea3e8 100644 --- a/perl_keyword.pl +++ b/perl_keyword.pl @@ -12,7 +12,8 @@ my @pos = qw(__DATA__ __END__ AUTOLOAD BEGIN CHECK DESTROY default defined split state study sub tr use undef UNITCHECK until unless when while y); -my @neg = qw(__FILE__ __LINE__ __PACKAGE__ and abs alarm atan2 accept bless +my @neg = qw(__FILE__ __LINE__ __PACKAGE__ __SUB__ + and abs alarm atan2 accept bless break bind binmode CORE cmp chr cos chop close chdir chomp chmod chown crypt chroot caller connect closedir continue die dump dbmopen dbmclose eq eof exp exit exec each endgrent endpwent diff --git a/pp.c b/pp.c index 47cf756..0126061 100644 --- a/pp.c +++ b/pp.c @@ -6162,6 +6162,14 @@ PP(pp_boolkeys) RETURN; } +PP(pp_runcv) +{ + dSP; + CV * const cv = find_runcv(NULL); + XPUSHs(CvUNIQUE(cv) ? &PL_sv_undef : sv_2mortal(newRV((SV *)cv))); + RETURN; +} + /* * Local variables: * c-indentation-style: bsd diff --git a/pp.sym b/pp.sym index 11e8f78..bdafb6e 100644 --- a/pp.sym +++ b/pp.sym @@ -414,5 +414,6 @@ Perl_pp_reach Perl_pp_rkeys Perl_pp_rvalues Perl_pp_transr +Perl_pp_runcv # ex: set ro: diff --git a/proto.h b/proto.h index c4df3e2..b621af6 100644 --- a/proto.h +++ b/proto.h @@ -3147,6 +3147,7 @@ PERL_CALLCONV OP * Perl_pp_right_shift(pTHX); PERL_CALLCONV OP * Perl_pp_rindex(pTHX); PERL_CALLCONV OP * Perl_pp_rkeys(pTHX); PERL_CALLCONV OP * Perl_pp_rmdir(pTHX); +PERL_CALLCONV OP * Perl_pp_runcv(pTHX); PERL_CALLCONV OP * Perl_pp_rv2av(pTHX); PERL_CALLCONV OP * Perl_pp_rv2cv(pTHX); PERL_CALLCONV OP * Perl_pp_rv2gv(pTHX); diff --git a/regen/keywords.pl b/regen/keywords.pl index 381e098..b19f2b1 100755 --- a/regen/keywords.pl +++ b/regen/keywords.pl @@ -64,6 +64,7 @@ NULL __FILE__ __LINE__ __PACKAGE__ +__SUB__ __DATA__ __END__ AUTOLOAD diff --git a/regen/opcode.pl b/regen/opcode.pl index bd3d55a..84d8b69 100755 --- a/regen/opcode.pl +++ b/regen/opcode.pl @@ -1106,3 +1106,5 @@ rvalues values on reference ck_each t% S # y///r transr transliteration (tr///) ck_match is" S + +runcv __SUB__ ck_null s0 diff --git a/toke.c b/toke.c index ef14c18..e750ee0 100644 --- a/toke.c +++ b/toke.c @@ -6898,6 +6898,10 @@ Perl_yylex(pTHX) : &PL_sv_undef)); TERM(THING); + case KEY___SUB__: + pl_yylval.opval = (OP*)newOP(OP_RUNCV, 0); + TERM(THING); + case KEY___DATA__: case KEY___END__: { GV *gv; @@ -10289,7 +10293,7 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) goto unknown; } - case 7: /* 29 tokens of length 7 */ + case 7: /* 30 tokens of length 7 */ switch (name[0]) { case 'D': @@ -10306,14 +10310,35 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) goto unknown; case '_': - if (name[1] == '_' && - name[2] == 'E' && - name[3] == 'N' && - name[4] == 'D' && - name[5] == '_' && - name[6] == '_') - { /* __END__ */ - return KEY___END__; + if (name[1] == '_') + { + switch (name[2]) + { + case 'E': + if (name[3] == 'N' && + name[4] == 'D' && + name[5] == '_' && + name[6] == '_') + { /* __END__ */ + return KEY___END__; + } + + goto unknown; + + case 'S': + if (name[3] == 'U' && + name[4] == 'B' && + name[5] == '_' && + name[6] == '_') + { /* __SUB__ */ + return -KEY___SUB__; + } + + goto unknown; + + default: + goto unknown; + } } goto unknown; ```
p5pRT commented 13 years ago

From @abigail

On Sun\, Dec 12\, 2010 at 12​:26​:07PM -0800\, Father Chrysostomos wrote​:

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

This patch adds a __SUB__ keyword that returns the current subroutine\, or undef for the main program\, a special block\, or an eval.

If there are no objections\, I will add docs and push this shortly before 5.13.8.

Technically\, it could break programs\, as in theory someone could have a sub named '__SUB__'. It's not something I worry about though.

I think this is going to be very handy. I see opportunity for obfuscation as well\, but that's just my twisted mind.

Abigail

p5pRT commented 13 years ago

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

p5pRT commented 13 years ago

From @cpansprout

On Dec 12\, 2010\, at 12​:36 PM\, Abigail via RT wrote​:

On Sun\, Dec 12\, 2010 at 12​:26​:07PM -0800\, Father Chrysostomos wrote​:

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

This patch adds a __SUB__ keyword that returns the current subroutine\, or undef for the main program\, a special block\, or an eval.

If there are no objections\, I will add docs and push this shortly before 5.13.8.

Technically\, it could break programs\, as in theory someone could have a sub named '__SUB__'. It's not something I worry about though.

I thought such names were reserved.

I think this is going to be very handy. I see opportunity for obfuscation as well\, but that's just my twisted mind.

Twisted\, eh? How about this?

()=@​==split" "\,"Just another Perl hacker\,\n"; print reverse@​=

@​@​=("Perl hacker\,\n"\,'Just another ')\, \, $@​=sub{print$@​[@​_]} \,   \, ()->$@​\,$@​->() \,

use constant{Just=>another=>Perl=>hacker=>};$\="\,\n"; print join" "\,map eval"sort $_\,$_"\,qw! Just Perl!

perl -e 'print do{{&{sub{"Just another Perl hacker\,\n"}}\,last}}'

perl5.12.2 -e '$_{0+\$_}="Just another Perl hacker\,\n";@​INC=sub{\\$_};print$_{require _};sub SCALAR{$_[0]};'

p5pRT commented 13 years ago

From @abigail

On Sun\, Dec 12\, 2010 at 12​:52​:08PM -0800\, Father Chrysostomos wrote​:

On Dec 12\, 2010\, at 12​:36 PM\, Abigail via RT wrote​:

On Sun\, Dec 12\, 2010 at 12​:26​:07PM -0800\, Father Chrysostomos wrote​:

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

This patch adds a __SUB__ keyword that returns the current subroutine\, or undef for the main program\, a special block\, or an eval.

If there are no objections\, I will add docs and push this shortly before 5.13.8.

Technically\, it could break programs\, as in theory someone could have a sub named '__SUB__'. It's not something I worry about though.

I thought such names were reserved.

If it is\, it's neither enforced\, or even protected by a warning​:

  $ perl -wE 'sub __SUB__ {sub {say "Foo"}} __SUB__ -> ()'   Foo   $

Abigail

p5pRT commented 13 years ago

From @rafl

Father Chrysostomos (via RT) \perlbug\-followup@&#8203;perl\.org writes​:

This patch adds a __SUB__ keyword that returns the current subroutine\, or undef for the main program\, a special block\, or an eval.

Using '__SUB__' made me think it was a compile-time constant such as __FILE__ and __LINE__. It isn't\, so I think it's not very good naming.

Why not make it look like a regular function or keyword\, such as

  sub {   print "$_[0]\n";   caller_cv(0)->($_[0] + 1) if $_[0] \< $arg;   }

In fact this is already available on CPAN as Devel​::Caller. Is this something common and useful enough to make it part of the core language? I'm not really convinced of that.

p5pRT commented 13 years ago

From @sciurius

Abigail \abigail@&#8203;abigail\.be writes​:

Technically\, it could break programs\, as in theory someone could have a sub named '__SUB__'. It's not something I worry about though.

I thought such names were reserved.

If it is\, it's neither enforced\, or even protected by a warning​:

Neither are subroutines/variable names with all UPPERCASE.

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

p5pRT commented 13 years ago

From @ikegami

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

p5pRT commented 13 years ago

From @sciurius

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

What would be the difference with (caller(0))[3] ?

-- Johan

p5pRT commented 13 years ago

From @demerphq

On 12 December 2010 21​:26\, Father Chrysostomos \perlbug\-followup@&#8203;perl\.org wrote​:

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

This patch adds a __SUB__ keyword that returns the current subroutine\, or undef for the main program\, a special block\, or an eval.

If there are no objections\, I will add docs and push this shortly before 5.13.8.

I first thought of adding this to make recursive lexicals subs easier to write (whenever they are added)​:

my sub foo { __SUB__->() }

my sub foo;  # the alternative my sub foo { foo() }

The really neat thing\, which I realised only after writing it\, is that it allows for recursive closures to be written much more simply​:

sub make_recursive_function {  my $arg = shift;  sub {    print "$_[0]\n";    __SUB__->($_[0] + 1) if $_[0] \< $arg;  } }

as opposed to​:

use Scalar​::Util; sub make_recursive_function {  my $arg = shift;  my $sub;  my $life_raft = $sub = sub {    print "$_[0]\n";    &$sub($_[0] + 1) if $_[0] \< $arg;  }  Scalar​::Util​::weaken($sub);  $sub; }

[Reminder to myself​: I need to add it to Opcode.pm as well.]

--- Flags​:    category=core    severity=wishlist --- Site configuration information for perl 5.13.7​:

Configured by sprout at Thu Dec  9 14​:53​:58 PST 2010.

Summary of my perl5 (revision 5 version 13 subversion 7) configuration​:  Snapshot of​: 9e9fdd5de1676d607ddf9b9f10b8df2659af3ded  Platform​:    osname=darwin\, osvers=10.4.0\, archname=darwin-2level    uname='darwin pint.local 10.4.0 darwin kernel version 10.4.0​: fri apr 23 18​:28​:53 pdt 2010; root​:xnu-1504.7.4~1release_i386 i386 '    config_args='-de -Dusedevel -DDEBUGGING'    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='cc'\, ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'\,    optimize='-O3 -g'\,    cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'    ccversion=''\, gccversion='4.2.1 (Apple Inc. build 5664)'\, 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 =' -fstack-protector -L/usr/local/lib'    libpth=/usr/local/lib /usr/lib    libs=-ldbm -ldl -lm -lutil -lc    perllibs=-ldl -lm -lutil -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=' -bundle -undefined dynamic_lookup -L/usr/local/lib -fstack-protector'

Locally applied patches​:

--- @​INC for perl 5.13.7​:    /usr/local/lib/perl5/site_perl/5.13.7/darwin-2level    /usr/local/lib/perl5/site_perl/5.13.7    /usr/local/lib/perl5/5.13.7/darwin-2level    /usr/local/lib/perl5/5.13.7    /usr/local/lib/perl5/site_perl    .

--- Environment for perl 5.13.7​:    DYLD_LIBRARY_PATH (unset)    HOME=/Users/sprout    LANG=en_US.UTF-8    LANGUAGE (unset)    LD_LIBRARY_PATH (unset)    LOGDIR (unset)    PATH=/usr/bin​:/bin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/X11/bin​:/usr/local/bin    PERL_BADLANG (unset)    SHELL=/bin/bash

diff --git a/embed.h b/embed.h index 5f846f5..f511965 100644 --- a/embed.h +++ b/embed.h @​@​ -1363\,6 +1363\,7 @​@​  #define pp_rindex()            Perl_pp_rindex(aTHX)  #define pp_rkeys()             Perl_pp_rkeys(aTHX)  #define pp_rmdir()             Perl_pp_rmdir(aTHX) +#define pp_runcv()             Perl_pp_runcv(aTHX)  #define pp_rv2av()             Perl_pp_rv2av(aTHX)  #define pp_rv2cv()             Perl_pp_rv2cv(aTHX)  #define pp_rv2gv()             Perl_pp_rv2gv(aTHX) diff --git a/keywords.h b/keywords.h index 526f3e4..1f63f06 100644 --- a/keywords.h +++ b/keywords.h @​@​ -16\,254 +16\,255 @​@​  #define KEY___FILE__           1  #define KEY___LINE__           2  #define KEY___PACKAGE__                3 -#define KEY___DATA__           4 -#define KEY___END__            5 -#define KEY_AUTOLOAD           6 -#define KEY_BEGIN              7 -#define KEY_UNITCHECK          8 -#define KEY_CORE               9 -#define KEY_DESTROY            10 -#define KEY_END                        11 -#define KEY_INIT               12 -#define KEY_CHECK              13 -#define KEY_abs                        14 -#define KEY_accept             15 -#define KEY_alarm              16 -#define KEY_and                        17 -#define KEY_atan2              18 -#define KEY_bind               19 -#define KEY_binmode            20 -#define KEY_bless              21 -#define KEY_break              22 -#define KEY_caller             23 -#define KEY_chdir              24 -#define KEY_chmod              25 -#define KEY_chomp              26 -#define KEY_chop               27 -#define KEY_chown              28 -#define KEY_chr                        29 -#define KEY_chroot             30 -#define KEY_close              31 -#define KEY_closedir           32 -#define KEY_cmp                        33 -#define KEY_connect            34 -#define KEY_continue           35 -#define KEY_cos                        36 -#define KEY_crypt              37 -#define KEY_dbmclose           38 -#define KEY_dbmopen            39 -#define KEY_default            40 -#define KEY_defined            41 -#define KEY_delete             42 -#define KEY_die                        43 -#define KEY_do                 44 -#define KEY_dump               45 -#define KEY_each               46 -#define KEY_else               47 -#define KEY_elsif              48 -#define KEY_endgrent           49 -#define KEY_endhostent         50 -#define KEY_endnetent          51 -#define KEY_endprotoent                52 -#define KEY_endpwent           53 -#define KEY_endservent         54 -#define KEY_eof                        55 -#define KEY_eq                 56 -#define KEY_eval               57 -#define KEY_exec               58 -#define KEY_exists             59 -#define KEY_exit               60 -#define KEY_exp                        61 -#define KEY_fcntl              62 -#define KEY_fileno             63 -#define KEY_flock              64 -#define KEY_for                        65 -#define KEY_foreach            66 -#define KEY_fork               67 -#define KEY_format             68 -#define KEY_formline           69 -#define KEY_ge                 70 -#define KEY_getc               71 -#define KEY_getgrent           72 -#define KEY_getgrgid           73 -#define KEY_getgrnam           74 -#define KEY_gethostbyaddr      75 -#define KEY_gethostbyname      76 -#define KEY_gethostent         77 -#define KEY_getlogin           78 -#define KEY_getnetbyaddr       79 -#define KEY_getnetbyname       80 -#define KEY_getnetent          81 -#define KEY_getpeername                82 -#define KEY_getpgrp            83 -#define KEY_getppid            84 -#define KEY_getpriority                85 -#define KEY_getprotobyname     86 -#define KEY_getprotobynumber   87 -#define KEY_getprotoent                88 -#define KEY_getpwent           89 -#define KEY_getpwnam           90 -#define KEY_getpwuid           91 -#define KEY_getservbyname      92 -#define KEY_getservbyport      93 -#define KEY_getservent         94 -#define KEY_getsockname                95 -#define KEY_getsockopt         96 -#define KEY_given              97 -#define KEY_glob               98 -#define KEY_gmtime             99 -#define KEY_goto               100 -#define KEY_grep               101 -#define KEY_gt                 102 -#define KEY_hex                        103 -#define KEY_if                 104 -#define KEY_index              105 -#define KEY_int                        106 -#define KEY_ioctl              107 -#define KEY_join               108 -#define KEY_keys               109 -#define KEY_kill               110 -#define KEY_last               111 -#define KEY_lc                 112 -#define KEY_lcfirst            113 -#define KEY_le                 114 -#define KEY_length             115 -#define KEY_link               116 -#define KEY_listen             117 -#define KEY_local              118 -#define KEY_localtime          119 -#define KEY_lock               120 -#define KEY_log                        121 -#define KEY_lstat              122 -#define KEY_lt                 123 -#define KEY_m                  124 -#define KEY_map                        125 -#define KEY_mkdir              126 -#define KEY_msgctl             127 -#define KEY_msgget             128 -#define KEY_msgrcv             129 -#define KEY_msgsnd             130 -#define KEY_my                 131 -#define KEY_ne                 132 -#define KEY_next               133 -#define KEY_no                 134 -#define KEY_not                        135 -#define KEY_oct                        136 -#define KEY_open               137 -#define KEY_opendir            138 -#define KEY_or                 139 -#define KEY_ord                        140 -#define KEY_our                        141 -#define KEY_pack               142 -#define KEY_package            143 -#define KEY_pipe               144 -#define KEY_pop                        145 -#define KEY_pos                        146 -#define KEY_print              147 -#define KEY_printf             148 -#define KEY_prototype          149 -#define KEY_push               150 -#define KEY_q                  151 -#define KEY_qq                 152 -#define KEY_qr                 153 -#define KEY_quotemeta          154 -#define KEY_qw                 155 -#define KEY_qx                 156 -#define KEY_rand               157 -#define KEY_read               158 -#define KEY_readdir            159 -#define KEY_readline           160 -#define KEY_readlink           161 -#define KEY_readpipe           162 -#define KEY_recv               163 -#define KEY_redo               164 -#define KEY_ref                        165 -#define KEY_rename             166 -#define KEY_require            167 -#define KEY_reset              168 -#define KEY_return             169 -#define KEY_reverse            170 -#define KEY_rewinddir          171 -#define KEY_rindex             172 -#define KEY_rmdir              173 -#define KEY_s                  174 -#define KEY_say                        175 -#define KEY_scalar             176 -#define KEY_seek               177 -#define KEY_seekdir            178 -#define KEY_select             179 -#define KEY_semctl             180 -#define KEY_semget             181 -#define KEY_semop              182 -#define KEY_send               183 -#define KEY_setgrent           184 -#define KEY_sethostent         185 -#define KEY_setnetent          186 -#define KEY_setpgrp            187 -#define KEY_setpriority                188 -#define KEY_setprotoent                189 -#define KEY_setpwent           190 -#define KEY_setservent         191 -#define KEY_setsockopt         192 -#define KEY_shift              193 -#define KEY_shmctl             194 -#define KEY_shmget             195 -#define KEY_shmread            196 -#define KEY_shmwrite           197 -#define KEY_shutdown           198 -#define KEY_sin                        199 -#define KEY_sleep              200 -#define KEY_socket             201 -#define KEY_socketpair         202 -#define KEY_sort               203 -#define KEY_splice             204 -#define KEY_split              205 -#define KEY_sprintf            206 -#define KEY_sqrt               207 -#define KEY_srand              208 -#define KEY_stat               209 -#define KEY_state              210 -#define KEY_study              211 -#define KEY_sub                        212 -#define KEY_substr             213 -#define KEY_symlink            214 -#define KEY_syscall            215 -#define KEY_sysopen            216 -#define KEY_sysread            217 -#define KEY_sysseek            218 -#define KEY_system             219 -#define KEY_syswrite           220 -#define KEY_tell               221 -#define KEY_telldir            222 -#define KEY_tie                        223 -#define KEY_tied               224 -#define KEY_time               225 -#define KEY_times              226 -#define KEY_tr                 227 -#define KEY_truncate           228 -#define KEY_uc                 229 -#define KEY_ucfirst            230 -#define KEY_umask              231 -#define KEY_undef              232 -#define KEY_unless             233 -#define KEY_unlink             234 -#define KEY_unpack             235 -#define KEY_unshift            236 -#define KEY_untie              237 -#define KEY_until              238 -#define KEY_use                        239 -#define KEY_utime              240 -#define KEY_values             241 -#define KEY_vec                        242 -#define KEY_wait               243 -#define KEY_waitpid            244 -#define KEY_wantarray          245 -#define KEY_warn               246 -#define KEY_when               247 -#define KEY_while              248 -#define KEY_write              249 -#define KEY_x                  250 -#define KEY_xor                        251 -#define KEY_y                  252 +#define KEY___SUB__            4 +#define KEY___DATA__           5 +#define KEY___END__            6 +#define KEY_AUTOLOAD           7 +#define KEY_BEGIN              8 +#define KEY_UNITCHECK          9 +#define KEY_CORE               10 +#define KEY_DESTROY            11 +#define KEY_END                        12 +#define KEY_INIT               13 +#define KEY_CHECK              14 +#define KEY_abs                        15 +#define KEY_accept             16 +#define KEY_alarm              17 +#define KEY_and                        18 +#define KEY_atan2              19 +#define KEY_bind               20 +#define KEY_binmode            21 +#define KEY_bless              22 +#define KEY_break              23 +#define KEY_caller             24 +#define KEY_chdir              25 +#define KEY_chmod              26 +#define KEY_chomp              27 +#define KEY_chop               28 +#define KEY_chown              29 +#define KEY_chr                        30 +#define KEY_chroot             31 +#define KEY_close              32 +#define KEY_closedir           33 +#define KEY_cmp                        34 +#define KEY_connect            35 +#define KEY_continue           36 +#define KEY_cos                        37 +#define KEY_crypt              38 +#define KEY_dbmclose           39 +#define KEY_dbmopen            40 +#define KEY_default            41 +#define KEY_defined            42 +#define KEY_delete             43 +#define KEY_die                        44 +#define KEY_do                 45 +#define KEY_dump               46 +#define KEY_each               47 +#define KEY_else               48 +#define KEY_elsif              49 +#define KEY_endgrent           50 +#define KEY_endhostent         51 +#define KEY_endnetent          52 +#define KEY_endprotoent                53 +#define KEY_endpwent           54 +#define KEY_endservent         55 +#define KEY_eof                        56 +#define KEY_eq                 57 +#define KEY_eval               58 +#define KEY_exec               59 +#define KEY_exists             60 +#define KEY_exit               61 +#define KEY_exp                        62 +#define KEY_fcntl              63 +#define KEY_fileno             64 +#define KEY_flock              65 +#define KEY_for                        66 +#define KEY_foreach            67 +#define KEY_fork               68 +#define KEY_format             69 +#define KEY_formline           70 +#define KEY_ge                 71 +#define KEY_getc               72 +#define KEY_getgrent           73 +#define KEY_getgrgid           74 +#define KEY_getgrnam           75 +#define KEY_gethostbyaddr      76 +#define KEY_gethostbyname      77 +#define KEY_gethostent         78 +#define KEY_getlogin           79 +#define KEY_getnetbyaddr       80 +#define KEY_getnetbyname       81 +#define KEY_getnetent          82 +#define KEY_getpeername                83 +#define KEY_getpgrp            84 +#define KEY_getppid            85 +#define KEY_getpriority                86 +#define KEY_getprotobyname     87 +#define KEY_getprotobynumber   88 +#define KEY_getprotoent                89 +#define KEY_getpwent           90 +#define KEY_getpwnam           91 +#define KEY_getpwuid           92 +#define KEY_getservbyname      93 +#define KEY_getservbyport      94 +#define KEY_getservent         95 +#define KEY_getsockname                96 +#define KEY_getsockopt         97 +#define KEY_given              98 +#define KEY_glob               99 +#define KEY_gmtime             100 +#define KEY_goto               101 +#define KEY_grep               102 +#define KEY_gt                 103 +#define KEY_hex                        104 +#define KEY_if                 105 +#define KEY_index              106 +#define KEY_int                        107 +#define KEY_ioctl              108 +#define KEY_join               109 +#define KEY_keys               110 +#define KEY_kill               111 +#define KEY_last               112 +#define KEY_lc                 113 +#define KEY_lcfirst            114 +#define KEY_le                 115 +#define KEY_length             116 +#define KEY_link               117 +#define KEY_listen             118 +#define KEY_local              119 +#define KEY_localtime          120 +#define KEY_lock               121 +#define KEY_log                        122 +#define KEY_lstat              123 +#define KEY_lt                 124 +#define KEY_m                  125 +#define KEY_map                        126 +#define KEY_mkdir              127 +#define KEY_msgctl             128 +#define KEY_msgget             129 +#define KEY_msgrcv             130 +#define KEY_msgsnd             131 +#define KEY_my                 132 +#define KEY_ne                 133 +#define KEY_next               134 +#define KEY_no                 135 +#define KEY_not                        136 +#define KEY_oct                        137 +#define KEY_open               138 +#define KEY_opendir            139 +#define KEY_or                 140 +#define KEY_ord                        141 +#define KEY_our                        142 +#define KEY_pack               143 +#define KEY_package            144 +#define KEY_pipe               145 +#define KEY_pop                        146 +#define KEY_pos                        147 +#define KEY_print              148 +#define KEY_printf             149 +#define KEY_prototype          150 +#define KEY_push               151 +#define KEY_q                  152 +#define KEY_qq                 153 +#define KEY_qr                 154 +#define KEY_quotemeta          155 +#define KEY_qw                 156 +#define KEY_qx                 157 +#define KEY_rand               158 +#define KEY_read               159 +#define KEY_readdir            160 +#define KEY_readline           161 +#define KEY_readlink           162 +#define KEY_readpipe           163 +#define KEY_recv               164 +#define KEY_redo               165 +#define KEY_ref                        166 +#define KEY_rename             167 +#define KEY_require            168 +#define KEY_reset              169 +#define KEY_return             170 +#define KEY_reverse            171 +#define KEY_rewinddir          172 +#define KEY_rindex             173 +#define KEY_rmdir              174 +#define KEY_s                  175 +#define KEY_say                        176 +#define KEY_scalar             177 +#define KEY_seek               178 +#define KEY_seekdir            179 +#define KEY_select             180 +#define KEY_semctl             181 +#define KEY_semget             182 +#define KEY_semop              183 +#define KEY_send               184 +#define KEY_setgrent           185 +#define KEY_sethostent         186 +#define KEY_setnetent          187 +#define KEY_setpgrp            188 +#define KEY_setpriority                189 +#define KEY_setprotoent                190 +#define KEY_setpwent           191 +#define KEY_setservent         192 +#define KEY_setsockopt         193 +#define KEY_shift              194 +#define KEY_shmctl             195 +#define KEY_shmget             196 +#define KEY_shmread            197 +#define KEY_shmwrite           198 +#define KEY_shutdown           199 +#define KEY_sin                        200 +#define KEY_sleep              201 +#define KEY_socket             202 +#define KEY_socketpair         203 +#define KEY_sort               204 +#define KEY_splice             205 +#define KEY_split              206 +#define KEY_sprintf            207 +#define KEY_sqrt               208 +#define KEY_srand              209 +#define KEY_stat               210 +#define KEY_state              211 +#define KEY_study              212 +#define KEY_sub                        213 +#define KEY_substr             214 +#define KEY_symlink            215 +#define KEY_syscall            216 +#define KEY_sysopen            217 +#define KEY_sysread            218 +#define KEY_sysseek            219 +#define KEY_system             220 +#define KEY_syswrite           221 +#define KEY_tell               222 +#define KEY_telldir            223 +#define KEY_tie                        224 +#define KEY_tied               225 +#define KEY_time               226 +#define KEY_times              227 +#define KEY_tr                 228 +#define KEY_truncate           229 +#define KEY_uc                 230 +#define KEY_ucfirst            231 +#define KEY_umask              232 +#define KEY_undef              233 +#define KEY_unless             234 +#define KEY_unlink             235 +#define KEY_unpack             236 +#define KEY_unshift            237 +#define KEY_untie              238 +#define KEY_until              239 +#define KEY_use                        240 +#define KEY_utime              241 +#define KEY_values             242 +#define KEY_vec                        243 +#define KEY_wait               244 +#define KEY_waitpid            245 +#define KEY_wantarray          246 +#define KEY_warn               247 +#define KEY_when               248 +#define KEY_while              249 +#define KEY_write              250 +#define KEY_x                  251 +#define KEY_xor                        252 +#define KEY_y                  253

 /* ex​: set ro​: */ diff --git a/opcode.h b/opcode.h index 122c67f..0a9f94d 100644 --- a/opcode.h +++ b/opcode.h @​@​ -398\,6 +398\,7 @​@​ EXTCONST char* const PL_op_name[] = {        "rkeys"\,        "rvalues"\,        "transr"\, +       "runcv"\,  };  #endif

@​@​ -775\,6 +776\,7 @​@​ EXTCONST char* const PL_op_desc[] = {        "keys on reference"\,        "values on reference"\,        "transliteration (tr///)"\, +       "__SUB__"\,  };  #endif

@​@​ -1166\,6 +1168\,7 @​@​ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */        Perl_pp_rkeys\,        Perl_pp_rkeys\,  /* Perl_pp_rvalues */        Perl_pp_trans\,  /* Perl_pp_transr */ +       Perl_pp_runcv\,  }  #endif  #ifdef PERL_PPADDR_INITED @​@​ -1554\,6 +1557\,7 @​@​ EXT Perl_check_t PL_check[] /* or perlvars.h */        Perl_ck_each\,           /* rkeys */        Perl_ck_each\,           /* rvalues */        Perl_ck_match\,          /* transr */ +       Perl_ck_null\,           /* runcv */  }  #endif  #ifdef PERL_CHECK_INITED @​@​ -1936\,6 +1940\,7 @​@​ EXTCONST U32 PL_opargs[] = {        0x00001b08\,     /* rkeys */        0x00001b08\,     /* rvalues */        0x00001804\,     /* transr */ +       0x00000004\,     /* runcv */  };  #endif

diff --git a/opnames.h b/opnames.h index 609c6e2..3e14f30 100644 --- a/opnames.h +++ b/opnames.h @​@​ -385\,10 +385\,11 @​@​ typedef enum opcode {        OP_RKEYS         = 367\,        OP_RVALUES       = 368\,        OP_TRANSR        = 369\, +       OP_RUNCV         = 370\,        OP_max  } opcode;

-#define MAXO 370 +#define MAXO 371  #define OP_phoney_INPUT_ONLY -1  #define OP_phoney_OUTPUT_ONLY -2

diff --git a/perl_keyword.pl b/perl_keyword.pl index 73128c3..9bea3e8 100644 --- a/perl_keyword.pl +++ b/perl_keyword.pl @​@​ -12\,7 +12\,8 @​@​ my @​pos = qw(__DATA__ __END__ AUTOLOAD BEGIN CHECK DESTROY default defined            split state study sub tr use undef UNITCHECK until            unless when while y);

-my @​neg = qw(__FILE__ __LINE__ __PACKAGE__ and abs alarm atan2 accept bless +my @​neg = qw(__FILE__ __LINE__ __PACKAGE__ __SUB__ +           and abs alarm atan2 accept bless            break bind binmode CORE cmp chr cos chop close chdir chomp chmod            chown crypt chroot caller connect closedir continue die dump            dbmopen dbmclose eq eof exp exit exec each endgrent endpwent diff --git a/pp.c b/pp.c index 47cf756..0126061 100644 --- a/pp.c +++ b/pp.c @​@​ -6162\,6 +6162\,14 @​@​ PP(pp_boolkeys)     RETURN;  }

+PP(pp_runcv) +{ +    dSP; +    CV * const cv = find_runcv(NULL); +    XPUSHs(CvUNIQUE(cv) ? &PL_sv_undef : sv_2mortal(newRV((SV *)cv))); +    RETURN; +} +  /*  * Local variables​:  * c-indentation-style​: bsd diff --git a/pp.sym b/pp.sym index 11e8f78..bdafb6e 100644 --- a/pp.sym +++ b/pp.sym @​@​ -414\,5 +414\,6 @​@​ Perl_pp_reach  Perl_pp_rkeys  Perl_pp_rvalues  Perl_pp_transr +Perl_pp_runcv

 # ex​: set ro​: diff --git a/proto.h b/proto.h index c4df3e2..b621af6 100644 --- a/proto.h +++ b/proto.h @​@​ -3147\,6 +3147\,7 @​@​ PERL_CALLCONV OP *        Perl_pp_right_shift(pTHX);  PERL_CALLCONV OP *     Perl_pp_rindex(pTHX);  PERL_CALLCONV OP *     Perl_pp_rkeys(pTHX);  PERL_CALLCONV OP *     Perl_pp_rmdir(pTHX); +PERL_CALLCONV OP *     Perl_pp_runcv(pTHX);  PERL_CALLCONV OP *     Perl_pp_rv2av(pTHX);  PERL_CALLCONV OP *     Perl_pp_rv2cv(pTHX);  PERL_CALLCONV OP *     Perl_pp_rv2gv(pTHX); diff --git a/regen/keywords.pl b/regen/keywords.pl index 381e098..b19f2b1 100755 --- a/regen/keywords.pl +++ b/regen/keywords.pl @​@​ -64\,6 +64\,7 @​@​ NULL  __FILE__  __LINE__  __PACKAGE__ +__SUB__  __DATA__  __END__  AUTOLOAD diff --git a/regen/opcode.pl b/regen/opcode.pl index bd3d55a..84d8b69 100755 --- a/regen/opcode.pl +++ b/regen/opcode.pl @​@​ -1106\,3 +1106\,5 @​@​ rvalues           values on reference                     ck_each         t%      S

 # y///r  transr         transliteration (tr///) ck_match        is"     S + +runcv          __SUB__                 ck_null         s0 diff --git a/toke.c b/toke.c index ef14c18..e750ee0 100644 --- a/toke.c +++ b/toke.c @​@​ -6898\,6 +6898\,10 @​@​ Perl_yylex(pTHX)                                         : &PL_sv_undef));            TERM(THING);

+       case KEY___SUB__​: +           pl_yylval.opval = (OP*)newOP(OP_RUNCV\, 0); +           TERM(THING); +        case KEY___DATA__​:        case KEY___END__​: {            GV *gv; @​@​ -10289\,7 +10293\,7 @​@​ Perl_keyword (pTHX_ const char *name\, I32 len\, bool all_keywords)           goto unknown;       }

-    case 7​: /* 29 tokens of length 7 */ +    case 7​: /* 30 tokens of length 7 */       switch (name[0])       {         case 'D'​: @​@​ -10306\,14 +10310\,35 @​@​ Perl_keyword (pTHX_ const char *name\, I32 len\, bool all_keywords)           goto unknown;

        case '_'​: -          if (name[1] == '_' && -              name[2] == 'E' && -              name[3] == 'N' && -              name[4] == 'D' && -              name[5] == '_' && -              name[6] == '_') -          {                                       /* __END__    */ -            return KEY___END__; +          if (name[1] == '_') +          { +            switch (name[2]) +            { +              case 'E'​: +                if (name[3] == 'N' && +                    name[4] == 'D' && +                    name[5] == '_' && +                    name[6] == '_') +                {                                 /* __END__          */ +                  return KEY___END__; +                } + +                goto unknown; + +              case 'S'​: +                if (name[3] == 'U' && +                    name[4] == 'B' && +                    name[5] == '_' && +                    name[6] == '_') +                {                                 /* __SUB__          */ +                  return -KEY___SUB__; +                } + +                goto unknown; + +              default​: +                goto unknown; +            }           }

          goto unknown;

I long ago suggested this\, but recommended it be associated to a variable​: $^SUB

And in fact rafael put a nearly complete module on cpan for this.

But i would love to see this added to the language.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 10​:26\, demerphq \demerphq@&#8203;gmail\.com wrote​:

On 12 December 2010 21​:26\, Father Chrysostomos [snip]

The really neat thing\, which I realised only after writing it\, is that it allows for recursive closures to be written much more simply​:

And this was exactly the reason i recommended a $^SUB "tied" variable for this purpose. Again\, great idea. ++ to you.

Perhaps if the back compat police dislike __SUB__ you can make it work with $^SUB.

cheers\, Yves

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 10​:29\, demerphq \demerphq@&#8203;gmail\.com wrote​:

On 13 December 2010 10​:26\, demerphq \demerphq@&#8203;gmail\.com wrote​:

On 12 December 2010 21​:26\, Father Chrysostomos [snip]

The really neat thing\, which I realised only after writing it\, is that it allows for recursive closures to be written much more simply​:

And this was exactly the reason i recommended a $^SUB "tied" variable for this purpose. Again\, great idea. ++ to you.

Perhaps if the back compat police dislike __SUB__ you can make it work with $^SUB.

For the record​: I originally proposed it be called ${^THIS_SUB} (which IS reserved - and special by nature iirc) in

Message-ID​: \9b18b3110706261235y5ea26d9w516e8444b293c32d@&#8203;mail\.gmail\.com Date​: Tue\, 26 Jun 2007 21​:35​:26 +0200 From​: demerphq \demerphq@&#8203;gmail\.com To​: p5p \perl5\-porters@&#8203;perl\.org Subject​: What about a ${^THIS_SUB} variable?

In that thread Rafael replied with the module Sub​::Current on cpan where it is exported as ROUTINE()

http​://search.cpan.org/~rgarcia/Sub-Current-0.02/lib/Sub/Current.pm

It was also discussed in a number or other threads.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @abigail

On Mon\, Dec 13\, 2010 at 09​:07​:00AM +0100\, Johan Vromans wrote​:

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

What would be the difference with (caller(0))[3] ?

Because the latter doesn't work?

  $ perl -wE '$f = sub {say "Hello"; (caller (0)) [3] -> () if @​_}; $f -> (1)'   Hello   Undefined subroutine &main​::__ANON__ called at -e line 1.   $

(caller (0)) [3] requires an entry in the symbol table - which not every sub has.

Abigail

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 10​:42\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 09​:07​:00AM +0100\, Johan Vromans wrote​:

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

What would be the difference with (caller(0))[3] ?

Because the latter doesn't work?

 $ perl -wE '$f = sub {say "Hello"; (caller (0)) [3] -> () if @​_}; $f -> (1)'  Hello  Undefined subroutine &main​::__ANON__ called at -e line 1.  $

(caller (0)) [3] requires an entry in the symbol table - which not every sub has.

Right. __SUB__ would have to resolve as a coderef\, otherwise the point FC made about recursive closures would be lost.

The whole idea is to have a non-refcount incremented identifier that resolves to a reference to the currently executing subroutine.

Its principle advantage would be that it would allow us to have recursive closures without the incredibly ugly hack workaround that is required to use such a thing without memory leaks\, and which almost nobody knows how to do right.

Johan​: do *you* know how to create a recursive closure that does not involve a memory leak or flushing the subname/method cache? Even if you do\, how many other programmers do you think know the recipe?

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 09​:07\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @sciurius

[Quoting demerphq\, on December 13 2010\, 10​:48\, in "Re​: [perl #80628] [P"]

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

Sounds like a very good idea to me.

My main objection against __SUB__ is that __XXX__ things are currently compile time constants\, hence we must avoid introducing __XXX__ things that are not. It doesn't contribute to Perl's popularity.

-- Johan

p5pRT commented 13 years ago

From @abigail

On Mon\, Dec 13\, 2010 at 11​:32​:45AM +0100\, Johan Vromans wrote​:

[Quoting demerphq\, on December 13 2010\, 10​:48\, in "Re​: [perl #80628] [P"]

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

Sounds like a very good idea to me.

My main objection against __SUB__ is that __XXX__ things are currently compile time constants\, hence we must avoid introducing __XXX__ things that are not. It doesn't contribute to Perl's popularity.

I wouldn't say __END__ and __DATA__ (probably the most well-known\, and certainly the most used __XXX__ thingies) are "compile-time constants".

So\, I don't really buy the "__SUB__ confuses me\, because it isn't a compile-time constant" argument.

__XXX__ things I know about\, in order how often I see it used in code​:

__END__​: Special token __DATA__​: Special token __WARN__​: Special literal for %SIG __DIE__​: Special literal for %SIG

\

__FILE__​: Compile-time constant __LINE__​: Compile-time constant

Now\, I'd prefer a short token\, and I certainly don't mind having a variable\, so $^SUB now wins for me. But __SUB__ doesn't shout "compile-time constant" to me. (What constant should it possibly be?)

Abigail

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 11​:42\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 11​:32​:45AM +0100\, Johan Vromans wrote​:

[Quoting demerphq\, on December 13 2010\, 10​:48\, in "Re​: [perl #80628] [P"]

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

Sounds like a very good idea to me.

My main objection against __SUB__ is that __XXX__ things are currently compile time constants\, hence we must avoid introducing __XXX__ things that are not. It doesn't contribute to Perl's popularity.

I wouldn't say __END__ and __DATA__ (probably the most well-known\, and certainly the most used __XXX__ thingies) are "compile-time constants".

So\, I don't really buy the "__SUB__ confuses me\, because it isn't a compile-time constant" argument.

__XXX__ things I know about\, in order how often I see it used in code​:

__END__​:   Special token __DATA__​:  Special token __WARN__​:  Special literal for %SIG __DIE__​:   Special literal for %SIG

\

__FILE__​:  Compile-time constant __LINE__​:  Compile-time constant

Now\, I'd prefer a short token\, and I certainly don't mind having a variable\, so $^SUB now wins for me. But __SUB__ doesn't shout "compile-time constant" to me. (What constant should it possibly be?)

I think johan meant it in the sense that you dont expect to be able to localize\, or assign to an __IDENTIFIER__\, which fits the use case for this feature.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @sciurius

[Quoting demerphq\, on December 13 2010\, 12​:33\, in "Re​: [perl #80628] [P"]

Now\, I'd prefer a short token\, and I certainly don't mind having a variable\, so $^SUB now wins for me.

I tend to agree\, even with $SUB (cf. $ARGV)\, but $^SUB has the correct amount of magic smell.

-- Johan

p5pRT commented 13 years ago

From @abigail

On Mon\, Dec 13\, 2010 at 12​:33​:24PM +0100\, demerphq wrote​:

On 13 December 2010 11​:42\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 11​:32​:45AM +0100\, Johan Vromans wrote​:

[Quoting demerphq\, on December 13 2010\, 10​:48\, in "Re​: [perl #80628] [P"]

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

Sounds like a very good idea to me.

My main objection against __SUB__ is that __XXX__ things are currently compile time constants\, hence we must avoid introducing __XXX__ things that are not. It doesn't contribute to Perl's popularity.

I wouldn't say __END__ and __DATA__ (probably the most well-known\, and certainly the most used __XXX__ thingies) are "compile-time constants".

So\, I don't really buy the "__SUB__ confuses me\, because it isn't a compile-time constant" argument.

__XXX__ things I know about\, in order how often I see it used in code​:

__END__​:   Special token __DATA__​:  Special token __WARN__​:  Special literal for %SIG __DIE__​:   Special literal for %SIG

\

__FILE__​:  Compile-time constant __LINE__​:  Compile-time constant

Now\, I'd prefer a short token\, and I certainly don't mind having a variable\, so $^SUB now wins for me. But __SUB__ doesn't shout "compile-time constant" to me. (What constant should it possibly be?)

I think johan meant it in the sense that you dont expect to be able to localize\, or assign to an __IDENTIFIER__\, which fits the use case for this feature.

Good point.

But that\, IMO\, would favour __SUB__ over $^SUB. The latter may give the suggestion you can assign to it\, or localize\, while "the current sub" isn't something I associate with as assignable from Perl land.

Abigail

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 13​:04\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 12​:33​:24PM +0100\, demerphq wrote​:

On 13 December 2010 11​:42\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 11​:32​:45AM +0100\, Johan Vromans wrote​:

[Quoting demerphq\, on December 13 2010\, 10​:48\, in "Re​: [perl #80628] [P"]

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

Sounds like a very good idea to me.

My main objection against __SUB__ is that __XXX__ things are currently compile time constants\, hence we must avoid introducing __XXX__ things that are not. It doesn't contribute to Perl's popularity.

I wouldn't say __END__ and __DATA__ (probably the most well-known\, and certainly the most used __XXX__ thingies) are "compile-time constants".

So\, I don't really buy the "__SUB__ confuses me\, because it isn't a compile-time constant" argument.

__XXX__ things I know about\, in order how often I see it used in code​:

__END__​:   Special token __DATA__​:  Special token __WARN__​:  Special literal for %SIG __DIE__​:   Special literal for %SIG

\

__FILE__​:  Compile-time constant __LINE__​:  Compile-time constant

Now\, I'd prefer a short token\, and I certainly don't mind having a variable\, so $^SUB now wins for me. But __SUB__ doesn't shout "compile-time constant" to me. (What constant should it possibly be?)

I think johan meant it in the sense that you dont expect to be able to localize\, or assign to an __IDENTIFIER__\, which fits the use case for this feature.

Good point.

But that\, IMO\, would favour __SUB__ over $^SUB. The latter may give the suggestion you can assign to it\, or localize\, while "the current sub" isn't something I associate with as assignable from Perl land.

Yes right. I'm happy with FC's patch\, and would like to see it go in.

The only that might be odd with it is that it would return a ref\, and the other things return simple scalar values.

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From zefram@fysh.org

demerphq wrote​:

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

A variable is a poor model for this. I think it's best accessed via something that looks like a function call. __SUB__ would be fine\, except for the convention of __FOO__ denoting a compile-time constant. A current_sub() function interface would be my preference. This can be very easily implemented in an XS module\, generating a custom op. Something like​:

  static OP *   pp_current_sub(pTHX)   {   dSP;   XPUSHs(cxstack[cxstack_ix].blk_sub.cv);   RETURN;   }

  static OP *   THX_ck_entersub_current_sub(pTHX_ OP *entersubop\, GV *namegv\, SV *ckobj)   {   OP *o;   ck_entersub_args_proto(entersubop\, namegv\, ckobj);   op_free(entersubop);   /* I haven't learned how to use the new custom-op stuff yet */   o = newOP(OP_PUSHMARK\, 0);   o->op_type = OP_RAND;   o->op_ppaddr = pp_current_sub;   return o;   }

  BOOT​:   {   CV *cscv = get_cv("Acme​::CurrentSub​::current_sub"\, 0);   cv_set_call_checker(cscv\, THX_ck_entersub_current_sub\, (SV*)cscv);   }

  void   current_sub(...)   PROTOTYPE​:   CODE​:   PERL_UNUSED_VAR(items);   croak("current_sub called as a function");

With a little more work\, this can be backported to older Perl versions that don't have cv_set_call_checker().

-zefram

p5pRT commented 13 years ago

From zefram@fysh.org

I wrote​:

XPUSHs(cxstack[cxstack_ix].blk_sub.cv);

Trying again​:

  XPUSHs(sv_2mortal(newRV_noinc((SV*)cxstack[cxstack_ix].blk_sub.cv)));

-zefram

p5pRT commented 13 years ago

From @abigail

On Mon\, Dec 13\, 2010 at 01​:38​:02PM +0100\, demerphq wrote​:

On 13 December 2010 13​:04\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 12​:33​:24PM +0100\, demerphq wrote​:

On 13 December 2010 11​:42\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 11​:32​:45AM +0100\, Johan Vromans wrote​:

[Quoting demerphq\, on December 13 2010\, 10​:48\, in "Re​: [perl #80628] [P"]

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

Sounds like a very good idea to me.

My main objection against __SUB__ is that __XXX__ things are currently compile time constants\, hence we must avoid introducing __XXX__ things that are not. It doesn't contribute to Perl's popularity.

I wouldn't say __END__ and __DATA__ (probably the most well-known\, and certainly the most used __XXX__ thingies) are "compile-time constants".

So\, I don't really buy the "__SUB__ confuses me\, because it isn't a compile-time constant" argument.

__XXX__ things I know about\, in order how often I see it used in code​:

__END__​:   Special token __DATA__​:  Special token __WARN__​:  Special literal for %SIG __DIE__​:   Special literal for %SIG

\

I forgot one here​:

  __PACKAGE__​: Compile-time constant

__FILE__​:  Compile-time constant __LINE__​:  Compile-time constant

Now\, I'd prefer a short token\, and I certainly don't mind having a variable\, so $^SUB now wins for me. But __SUB__ doesn't shout "compile-time constant" to me. (What constant should it possibly be?)

I think johan meant it in the sense that you dont expect to be able to localize\, or assign to an __IDENTIFIER__\, which fits the use case for this feature.

Good point.

But that\, IMO\, would favour __SUB__ over $^SUB. The latter may give the suggestion you can assign to it\, or localize\, while "the current sub" isn't something I associate with as assignable from Perl land.

Yes right. I'm happy with FC's patch\, and would like to see it go in.

The only that might be odd with it is that it would return a ref\, and the other things return simple scalar values.

Yes\, but people do write "__PACKAGE__ -> ... ()" without being freaked out. "__SUB__ -> ()" isn't visually that much different\, even if one returns a string\, the other a code ref. For a typical use\, the user does not have to care.

Abigail

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 13​:59\, Zefram \zefram@&#8203;fysh\.org wrote​:

demerphq wrote​:

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

A variable is a poor model for this.  I think it's best accessed via something that looks like a function call.  __SUB__ would be fine\, except for the convention of __FOO__ denoting a compile-time constant.

Yes. But I think people can deal with that\, it isnt much different from __PACKAGE__.

A current_sub() function interface would be my preference.  This can be very easily implemented in an XS module\, generating a custom op. Something like​:

That is done by Rafael in Sub​::Current. He uses ROUTINE() for this purpose.

Yves.

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @lizmat

On Dec 13\, 2010\, at 5​:05 PM\, demerphq wrote​:

On 13 December 2010 13​:59\, Zefram \zefram@&#8203;fysh\.org wrote​:

demerphq wrote​:

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

A variable is a poor model for this. I think it's best accessed via something that looks like a function call. __SUB__ would be fine\, except for the convention of __FOO__ denoting a compile-time constant.

Yes. But I think people can deal with that\, it isnt much different from __PACKAGE__.

Please note that __PACKAGE__ and __LINE__ are settable nonetheless\, using #line and -package- .

A current_sub() function interface would be my preference. This can be very easily implemented in an XS module\, generating a custom op. Something like​: That is done by Rafael in Sub​::Current. He uses ROUTINE() for this purpose.

FWIW\, $^SUB feels more natural to me.

Liz

p5pRT commented 13 years ago

From @ikegami

On Mon\, Dec 13\, 2010 at 3​:07 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

What would be the difference with (caller(0))[3] ?

caller[3] doesn't work for anon subs.

perl -E"sub { say( (caller(0))[3] ) }->()" main​::__ANON__

It was specifically proposed that __SUB__ would return a reference in at least that case.

It's more like SUPER than __FILE__ in a sense. Maybe something without dashes would be more appropriate.

- Eric

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 17​:09\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Mon\, Dec 13\, 2010 at 3​:07 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

What would be the difference with (caller(0))[3] ?

caller[3] doesn't work for anon subs.

perl -E"sub { say( (caller(0))[3] ) }->()" main​::__ANON__

It was specifically proposed that __SUB__ would return a reference in at least that case.

It seen's to me that it MUST return a reference in ALL situations.

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @demerphq

On 12 December 2010 21​:26\, Father Chrysostomos \perlbug\-followup@&#8203;perl\.org wrote​:

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

This patch adds a __SUB__ keyword that returns the current subroutine\, or undef for the main program\, a special block\, or an eval.

If there are no objections\, I will add docs and push this shortly before 5.13.8.

I first thought of adding this to make recursive lexicals subs easier to write (whenever they are added)​:

my sub foo { __SUB__->() }

my sub foo;  # the alternative my sub foo { foo() }

The really neat thing\, which I realised only after writing it\, is that it allows for recursive closures to be written much more simply​:

sub make_recursive_function {  my $arg = shift;  sub {    print "$_[0]\n";    __SUB__->($_[0] + 1) if $_[0] \< $arg;  } }

as opposed to​:

use Scalar​::Util; sub make_recursive_function {  my $arg = shift;  my $sub;  my $life_raft = $sub = sub {    print "$_[0]\n";    &$sub($_[0] + 1) if $_[0] \< $arg;  }  Scalar​::Util​::weaken($sub);  $sub; }

And this demonstrates why the patch would be useful.

Even FC got the recipe wrong. :-)

It should return $life_raft\, not $sub\, otherwise $sub will be a "dead weakref"\, and the sub freed by the time this code exits.

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 17​:09\, Elizabeth Mattijsen \liz@&#8203;dijkmat\.nl wrote​:

On Dec 13\, 2010\, at 5​:05 PM\, demerphq wrote​:

On 13 December 2010 13​:59\, Zefram \zefram@&#8203;fysh\.org wrote​:

demerphq wrote​:

This is why i proposed using a $^THIS_SUB "magic tied var" for the purpose.

A variable is a poor model for this.  I think it's best accessed via something that looks like a function call.  __SUB__ would be fine\, except for the convention of __FOO__ denoting a compile-time constant.

Yes. But I think people can deal with that\, it isnt much different from __PACKAGE__.

Please note that __PACKAGE__ and __LINE__ are settable nonetheless\, using #line and -package- .

Yes I did consider that. But in both cases you dont modify __PACKAGE__ directly\, but instead via some other mechanism.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From zefram@fysh.org

Given that (a) there are already multiple versions of this on CPAN\, (b) there are competing versions of the semantics\, and (c) it's easy to implement a new version on CPAN where the existing versions don't provide the desired semantics\, it seems to me that the right place for this isn't the core\, it's CPAN.

-zefram

p5pRT commented 13 years ago

From @rafl

Zefram \zefram@&#8203;fysh\.org writes​:

Given that (a) there are already multiple versions of this on CPAN\, (b) there are competing versions of the semantics\, and (c) it's easy to implement a new version on CPAN where the existing versions don't provide the desired semantics\, it seems to me that the right place for this isn't the core\, it's CPAN.

+1

p5pRT commented 13 years ago

From @abigail

On Mon\, Dec 13\, 2010 at 05​:26​:29PM +0100\, demerphq wrote​:

On 13 December 2010 17​:09\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Mon\, Dec 13\, 2010 at 3​:07 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

What would be the difference with (caller(0))[3] ?

caller[3] doesn't work for anon subs.

perl -E"sub { say( (caller(0))[3] ) }->()" main​::__ANON__

It was specifically proposed that __SUB__ would return a reference in at least that case.

It seen's to me that it MUST return a reference in ALL situations.

I agree. Do one thing in one case\, and another in another case doesn't seem like a win situation to me. At least\, not here. You certainly shouldn't have to change the body of a sub if you change it from an anon sub to a named one.

It's more like SUPER than __FILE__ in a sense. Maybe something without dashes would be more appropriate.

I don't think so. While "SUB" is different from "sub"\, I'm not very keen to have two keywords that only differ in case. And anything else without underscores has the same problem as any other new keyword​: possible clashes.

Abigail

p5pRT commented 13 years ago

From @ikegami

On Mon\, Dec 13\, 2010 at 11​:47 AM\, Abigail \abigail@&#8203;abigail\.be wrote​:

It's more like SUPER than __FILE__ in a sense. Maybe something without dashes would be more appropriate.

I don't think so. While "SUB" is different from "sub"\, I'm not very keen to have two keywords that only differ in case. And anything else without underscores has the same problem as any other new keyword​: possible clashes.

Noone suggested it should be "SUB". I was thinking of "THIS_SUB". Someone else also came up with that name\, so I didn't mention it.

- Eric

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 17​:33\, Zefram \zefram@&#8203;fysh\.org wrote​:

Given that (a) there are already multiple versions of this on CPAN\, (b) there are competing versions of the semantics\, and (c) it's easy to implement a new version on CPAN where the existing versions don't provide the desired semantics\, it seems to me that the right place for this isn't the core\, it's CPAN.

Personally I think that Scalar​::Util\, Data​::Alias and friends taught us the lesson that the above are poor justifications to argue that something should be on CPAN or be part of core.

The reasons I see for putting it in core are​: a) it needs XS to be implemented\, b) the XS would be maintained by the core dev team\, c) by putting it in core we guarantee to our users that a very useful feature will always be available in perls following it\, d) it replaces an extremely awkward recipe that involves a module (Scalar​::Util) that after much debate and gnashing of teeth pretty much all agreed should have been in core in the first place - repeating such an error with a replacement for one of Scalar​::Utils routines seems most illogical.

With a CPAN module there is no contract between Perl and the community that something will be reliably available.

A CPAN module on the other may fall out of sync with perl and be abandoned by its author or otherwise go unsupported. We have seen this with Data​::Alias.

We have also seen that in many environments it is anywhere from nearly impossible to quite difficult to get non-standard modules installed at all\, let alone ones that require compiling XS code. We have seen both of these problems with Scalar​::Util. (I have personal experience of this one.)

This is a language feature that allows us to do something that is definitely non-trivial\, useful\, and likely to be widely adopted. It should BE part of the language\, not a nice-to-have after market bolt-on.

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 17​:47\, Abigail \abigail@&#8203;abigail\.be wrote​:

On Mon\, Dec 13\, 2010 at 05​:26​:29PM +0100\, demerphq wrote​:

On 13 December 2010 17​:09\, Eric Brine \ikegami@&#8203;adaelis\.com wrote​:

On Mon\, Dec 13\, 2010 at 3​:07 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

[Quoting Eric Brine\, on December 13 2010\, 02​:51\, in "Re​: [perl #80628] [P"]

On Mon\, Dec 13\, 2010 at 2​:09 AM\, Johan Vromans \jvromans@&#8203;squirrel\.nl wrote​:

More important is whether it is a keyword\, or a compile time constant like __FILE__ and __LINE__.

-- Johan

As proposed\, it's not constant.

Then please do not call it __SUB__.

What would be the difference with (caller(0))[3] ?

caller[3] doesn't work for anon subs.

perl -E"sub { say( (caller(0))[3] ) }->()" main​::__ANON__

It was specifically proposed that __SUB__ would return a reference in at least that case.

It seen's to me that it MUST return a reference in ALL situations.

I agree. Do one thing in one case\, and another in another case doesn't seem like a win situation to me. At least\, not here. You certainly shouldn't have to change the body of a sub if you change it from an anon sub to a named one.

And the fact that it not returning a reference would almost certainly lead to bugs.

For instance the same kind of problem we see here​:

$ perl -MCarp -le'sub foo { confess "foo" } sub baz { confess "baz" } *bar=&foo; *foo=&baz; bar()' foo at -e line 1   main​::foo called at -e line 1

If we returned anything but a code reference I reckon one could cook up something like this to cause a bunch of edge-case insanity. (Consider how much worse it gets when you add localized subroutines to the mix...)

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @obra

I'd rather this functionality live on CPAN until there's a clear consensus that it should be in core and about what it should be named.

On Mon\, Dec 13\, 2010 at 05​:35​:45PM +0100\, Florian Ragwitz wrote​:

Zefram \zefram@&#8203;fysh\.org writes​:

Given that (a) there are already multiple versions of this on CPAN\, (b) there are competing versions of the semantics\, and (c) it's easy to implement a new version on CPAN where the existing versions don't provide the desired semantics\, it seems to me that the right place for this isn't the core\, it's CPAN.

+1

--

p5pRT commented 13 years ago

From @demerphq

On 13 December 2010 21​:17\, Jesse Vincent \jesse@&#8203;fsck\.com wrote​:

I'd rather this functionality live on CPAN until there's a clear consensus that it should be in core and about what it should be named.

Jesse noted to me in IRC that this is due to the upcoming code freeze\, which makes a lot of sense.

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @obra

On Mon\, Dec 13\, 2010 at 03​:17​:11PM -0500\, Jesse Vincent wrote​:

I'd rather this functionality live on CPAN until there's a clear consensus that it should be in core and about what it should be named.

I somewhat misphrased this - We're very close to the contentious-feature-freeze for 5.14. And this is clearly contentious. I'd much rather it get better sorted out before we take it into blead. To me\, it makes sense that it get beaten around a bit before we think about the eventual result for 5.16.

p5pRT commented 13 years ago

From @nwc10

On Mon\, Dec 13\, 2010 at 07​:03​:32PM +0100\, demerphq wrote​:

We have also seen that in many environments it is anywhere from nearly impossible to quite difficult to get non-standard modules installed at all\, let alone ones that require compiling XS code. We have seen both of these problems with Scalar​::Util. (I have personal experience of this one.)

You're proposing a technical fix to a political problem.

We can't include all of CPAN in the core just because other people wish to externalize the costs of resolve their issues.

This is one of my hot buttons and I will argue against it until I am driven away from Perl 5.

Nicholas Clark

p5pRT commented 13 years ago

From @demerphq

On 14 December 2010 18​:10\, Nicholas Clark \nick@&#8203;ccl4\.org wrote​:

On Mon\, Dec 13\, 2010 at 07​:03​:32PM +0100\, demerphq wrote​:

We have also seen that in many environments it is anywhere from nearly impossible to quite difficult to get non-standard modules installed at all\, let alone ones that require compiling XS code. We have seen both of these problems with Scalar​::Util. (I have personal experience of this one.)

You're proposing a technical fix to a political problem.

On one level yes\, on another level no. Its a technical problem that it is quite difficult to make recursive closures. The existing technical solution for doing so is pretty sad. The proiposed solution is vaslty superior. So why should Perl essentially endorse the shit one and then say "but the best way you need to install extra modules"

On the other hand yes\, we have devs in our community who work in environments that can be quite restrictive. Your position basically amounts to saying that you don't care about their opinion or needs. I dont think that is the way our community should work and I definitely dont think it is a productive attitude.

We can't include all of CPAN in the core just because other people wish to externalize the costs of resolve their issues.

This is a straw man argument. Nobody is arguing about including all of CPAN.

We are arguing about including critical XS code that cannot reasonably be simulated in Perl code and which serves a function which essentially cannot be implemented without XS.

This doesn't apply to pure perl as there is always a workaround in that a user can always just C&P the code into their own code base if necessary -- effectively fork the perl code.

This DOES NOT apply to XS code. And even with XS code its not like anyone is arguing that this applies to a lot code\, but rather to a critical select few pieces that arguably should have been in perl from the beginning.

This is one of my hot buttons and I will argue against it until I am driven away from Perl 5.

I don't really like the threat here Nicholas\, especially given it is in regard to a position that nobody has taken.

If you really have a good argument for why this idea shouldn't move forward then post it\, but this line about including all of cpan is just bogus. Bring it up when somebody actually makes that argument ok?

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 13 years ago

From @leonerd

On Mon\, Dec 13\, 2010 at 10​:47​:01AM +0100\, demerphq wrote​:

The whole idea is to have a non-refcount incremented identifier that resolves to a reference to the currently executing subroutine.

use CPS qw( kwhile );

kwhile(   sub { my ( $knext ) = @​_;   .....

  $knext->()   } );

HTH\,

-- Paul "LeoNerd" Evans

leonerd@​leonerd.org.uk ICQ# 4135350 | Registered Linux# 179460 http​://www.leonerd.org.uk/

p5pRT commented 13 years ago

From @leonerd

On Mon\, Dec 13\, 2010 at 04​:33​:19PM +0000\, Zefram wrote​:

Given that (a) there are already multiple versions of this on CPAN\, (b) there are competing versions of the semantics\, and (c) it's easy to implement a new version on CPAN where the existing versions don't provide the desired semantics\, it seems to me that the right place for this isn't the core\, it's CPAN.

+1

First off\, there's callee

  http​://search.cpan.org/~marcel/callee-1.100820/lib/callee.pm

Secondly\, if you want it for the purpose of recursive functions\, try CPS

  http​://search.cpan.org/~pevans/CPS-0.10/lib/CPS.pm

  use CPS qw( kwhile );

  kwhile(   sub { my ( $knext ) = @​_;   ....

  $knext->();   }   );

It also includes some added magic to not blow up the stack if you call it "synchronously"\, it turns into a real tailcall implemented by a while loop\, so the stack doesn't get consumed. Ofcourse you can also store the $knext closure somewhere else to invoke later.

CPS is pure-perl.

-- Paul "LeoNerd" Evans

leonerd@​leonerd.org.uk ICQ# 4135350 | Registered Linux# 179460 http​://www.leonerd.org.uk/

p5pRT commented 13 years ago

From zefram@fysh.org

demerphq wrote​:

The whole idea is to have a non-refcount incremented identifier that resolves to a reference to the currently executing subroutine.

This can actually be achieved without either a statically self-referential function definition (requiring weak refs) or grubbing around in the runtime stack. Behold\, the non-recursive definition of the recursive implementation of factorial​:

  my $w = sub { my($v\, $x) = @​_;   sub { $x->(sub { $v->($v\, $x)->(@​_) }\, @​_) } };   my $y = sub { $w->($w\, $_[0]) };

  my $factorial =   $y->(sub { $_[1] == 0 ? 1 : $_[1] * $_[0]->($_[1] - 1) });

  print $factorial->(5)\, "\n";

This technique can be extended to arbitrarily many mutually-recursive functions\, an area where __SUB__/${^SUB} falls down.

(Thanks to LeoNerd for inspiring me to go in a theoretical direction.)

-zefram

p5pRT commented 12 years ago

From @cpansprout

On Mon Dec 13 13​:35​:19 2010\, jesse wrote​:

On Mon\, Dec 13\, 2010 at 03​:17​:11PM -0500\, Jesse Vincent wrote​:

I'd rather this functionality live on CPAN until there's a clear consensus that it should be in core and about what it should be named.

I somewhat misphrased this - We're very close to the contentious-feature-freeze for 5.14. And this is clearly contentious. I'd much rather it get better sorted out before we take it into blead. To me\, it makes sense that it get beaten around a bit before we think about the eventual result for 5.16.

OK\, now that we’re past that\, let me address some objections that came up​:

1) That __SUB__ is not a compile-time constant like its predecessors.

That __PACKAGE__ and __LINE__ are compile-time constants is an implementation detail. __PACKAGE__’s being a compile-time directive actually causes a bug in some edge cases\, so that is not set in stone. __SUB__ *can* be a compile-time constant in subroutines that do not close over variables. That optimisation just hasn’t been written yet.

2) That this should be a CPAN module\, not part of core.

One reason I think we should have this in core is that JavaScript supports it (arguments.callee)\, which makes Perl look bad.

And the symmetry with package/__PACKAGE__ is nice​: package foo { ... my $pack = __PACKAGE__ ... } sub foo { ... my $sub = __SUB__ ... }

p5pRT commented 12 years ago

From @sciurius

"Father Chrysostomos via RT" \perlbug\-followup@&#8203;perl\.org writes​:

1) That __SUB__ is not a compile-time constant like its predecessors. ... And the symmetry with package/__PACKAGE__ is nice​: package foo { ... my $pack = __PACKAGE__ ... } sub foo { ... my $sub = __SUB__ ... }

I revert my former objections. You have my blessing.

-- Johan

p5pRT commented 12 years ago

From @sciurius

"Father Chrysostomos via RT" \perlbug\-followup@&#8203;perl\.org writes​:

2) That this should be a CPAN module\, not part of core.

Some finetuning.

1. CPAN module means​: a bunch of Perl and XS (if necessary) that can be   added to a suitable Perl distribution. Note that building and   installing modules\, especially if they involve XS code\, is not always   trivial.

  Programs need to 'use' Some​::Thing to use it.

2. Core means​: it's there and works with this and all future Perl   distributions.

2a. It can still be a module; 'use' Some​::Thing is required.   Always safe.

2b. It can be a feature; 'use feature' or equivalent is required.   If it could break existing code.

2c. It can be built-in. It's just there.   Only if it cannot break existing code.

Technically\, anything new can be implemented in any of the above ways. Which of the ways it will end up is sometimes technical (e.g.\, another piece of Core wants to use it) but mostly political (i.e.\, the powers in charge like it).

Considering all this\, I'd vote for __SUB__ to fall in category 2c.

-- Johan

p5pRT commented 12 years ago

From @xdg

On Mon\, Dec 13\, 2010 at 7​:04 AM\, Abigail \abigail@&#8203;abigail\.be wrote​:

But that\, IMO\, would favour __SUB__ over $^SUB. The latter may give the suggestion you can assign to it\, or localize\, while "the current sub" isn't something I associate with as assignable from Perl land.

+1

p5pRT commented 12 years ago

From zefram@fysh.org

Since a satisfactorily functional version of __SUB__ already exists on CPAN\, in the form of Sub​::Current\, it appears to me that we should be thinking in terms of developing Sub​::Current\, rather than building something new in the core. Sub​::Current provides an established interface for invoking this feature\, and it is an interface that causes absolutely no complication around feature flags and Perl-version portability.

The specific name "__SUB__" can easily be added to Sub​::Current alongside its existing "ROUTINE" (*__SUB__ = \&ROUTINE). Its performance can also be improved within the confines of the module format​: it can use cv_set_call_checker and a custom op\, along the lines of the rough version that I posted upthread\, to reduce the cost of __SUB__ execution from a sub call to a single op.

If this feature is important enough that it ought to be available to users who don't have a compiler\, or if we really need to be able to tick a box on a comparison chart that says this feature is "included in Perl"\, then we should dual-life Sub​::Current. We can thus get the installation and maintenance characteristics of the core without requiring a new interface or any of the other complications of a true built-in.

I'm happy to help tweak the Sub​::Current implementation. I'm neutral on whether it should be dual-lifed. I'm -1 on turning any equivalent of it into a core built-in.

-zefram