develooper Front page | perl.perl5.porters | Postings from December 2010

Re: [perl #80628] [PATCH] __SUB__

Thread Previous | Thread Next
From:
demerphq
Date:
December 13, 2010 01:26
Subject:
Re: [perl #80628] [PATCH] __SUB__
Message ID:
AANLkTikFZLDTV5jQLcd6-FLjkrmn99xkvXcQunSKjHRe@mail.gmail.com
On 12 December 2010 21:26, Father Chrysostomos
<perlbug-followup@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/"

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About