Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

/r modifier on substitutions - variant returning undef if no match #12245

Open
p5pRT opened this issue Jul 3, 2012 · 7 comments
Open

/r modifier on substitutions - variant returning undef if no match #12245

p5pRT opened this issue Jul 3, 2012 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 3, 2012

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

Searchable as RT113962$

@p5pRT
Copy link
Author

p5pRT commented Jul 3, 2012

From @epa

Created by @epa

The new /r flag introduced for the s/// and tr/// operators in perl
5.14 is useful, but not as useful as it could be. Careful programming
will often check that the substitution matched​:

  my $old = 'cat';
  (my $new = $old) =~ s/cat/dog/ or die;

While the intention of /r is to simplify the use of substitution,
partly in idioms like the above and partly inside map {}, it is hard
to use it if you wanted to check that the substitution succeeded.
The code above cannot be straightforwardly rewritten using /r and
nor can you straightforwardly map {} over an array performing a
substitution on each item and checking it succeeded.

I suggest a variant which performs the substitution and returns
either the new string, or undef if no match. Suppose the modifier
/R is used for this purpose. Then

  my $new = $old =~ s/cat/dog/R // die;

  my @​new = map { s/cat/dog/R // die } @​old;

Perl Info

Flags:
    category=core
    severity=wishlist

This perlbug was built using Perl 5.14.2 in the Fedora build system.
It is being executed now by Perl 5.14.2 - Wed May 30 15:40:46 UTC 2012.

Site configuration information for perl 5.14.2:

Configured by Red Hat, Inc. at Wed May 30 15:40:46 UTC 2012.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration:
   
  Platform:
    osname=linux, osvers=2.6.32-220.4.1.el6.x86_64,
archname=x86_64-linux-thread-multi
    uname='linux x86-17.phx2.fedoraproject.org 2.6.32-220.4.1.el6.x86_64
#1 smp thu jan 19 14:50:54 est 2012 x86_64 x86_64 x86_64 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4  -m64 -mtune=generic
-Dccdlflags=-Wl,--enable-new-dtags -DDEBUGGING=-g -Dversion=5.14.2
-Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red
Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local
-Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5
-Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl
-Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl
-Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64
/usr/lib64 -Duseshrplib -Dusethreads -Duseithreads
-Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db
-Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio
-Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly
-Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto
-Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto
-Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing
-pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe
-fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.6.3 20120306 (Red Hat 4.6.3-2)',
gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -fstack-protector'
    libpth=/usr/local/lib64 /lib64 /usr/lib64
    libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread
-lc -lgdbm_compat
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.14.90'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef,
ccdlflags='-Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m64 -mtune=generic'

Locally applied patches:
    


@INC for perl 5.14.2:
    /home/eda/lib/perl5//x86_64-linux-thread-multi
    /home/eda/lib/perl5/
    /usr/local/lib64/perl5
    /usr/local/share/perl5
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5
    .


Environment for perl 5.14.2:
    HOME=/home/eda
    LANG=en_GB.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=C
    LC_CTYPE=en_GB.UTF-8
    LC_MESSAGES=en_GB.UTF-8
    LC_MONETARY=en_GB.UTF-8
    LC_NUMERIC=en_GB.UTF-8
    LC_TIME=en_GB.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
 
PATH=/home/eda/bin:/home/eda/bin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr
/sbin:/sbin:/usr/sbin
    PERL5LIB=/home/eda/lib/perl5/
    PERL_BADLANG (unset)
    SHELL=/bin/bash



______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http://www.symanteccloud.com
______________________________________________________________________

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2012

From @rjbs

On Tue Jul 03 03​:01​:56 2012, eda@​waniasset.com wrote​:

...

my $old = 'cat';
\(my $new = $old\) =~ s/cat/dog/ or die;

[...]
my $new = $old =~ s/cat/dog/R // die;

My feeling is that in this case, the user should simply use the non-r form. I am open to hear
more on this, but I think this is not worth the complexity of Yet Another Postfix Modifier.

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2012

From @epa

Ricardo SIGNES via RT <perlbug-followup <at> perl.org> writes​:

my $new = $old =~ s/cat/dog/R // die;

I think this is not worth the complexity of Yet Another Postfix Modifier.

You could well be right. In my experience, checking that the match succeeded is
the common case; it is rare that you want to substitute some text and
continue whether it succeeded or not (except for normalization operations like
s/\s+/ /g, which tend to be applied as in-place modifications rather than
assignments to a new scalar). So I would have said that /r is the rarely-used
case which does not merit yet another modifier, at least based on auditing my
own code. However, /r is already in the language and /R is not.

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

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2012

From @Leont

On Tue, Jul 24, 2012 at 12​:04 PM, Ed Avis <eda@​waniasset.com> wrote​:

You could well be right. In my experience, checking that the match succeeded is
the common case; it is rare that you want to substitute some text and
continue whether it succeeded or not (except for normalization operations like
s/\s+/ /g, which tend to be applied as in-place modifications rather than
assignments to a new scalar). So I would have said that /r is the rarely-used
case which does not merit yet another modifier, at least based on auditing my
own code. However, /r is already in the language and /R is not.

My experience is different. I use /r quite regularly, and have an
increasingly hard time imagining how we lived happily without it. I've
even used in on tr once or twice (which is pretty much all of my uses
of tr recently anyway).

Leon

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2012

From @xdg

On Tue, Jul 3, 2012 at 6​:01 AM, Ed Avis <perlbug-followup@​perl.org> wrote​:

I suggest a variant which performs the substitution and returns
either the new string, or undef if no match. Suppose the modifier
/R is used for this purpose. Then

Yes, but what if the original string was undef? (warnings aside) We
can't use a value to signal an exception in a function that takes a
value and returns a value.

Even if semantics could be worked out (die unless match?) I agree with
Ricardo that it's not worth another modifier.

I do think the documentation might need to reflect this issue and
perhaps add the suggestion to do it the old way if the success of the
match is important.

-- David

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2012

From @ikegami

On Tue, Jul 24, 2012 at 5​:04 AM, Ed Avis <eda@​waniasset.com> wrote​:

In my experience, checking that the match succeeded is
the common case; it is rare that you want to substitute some text and
continue whether it succeeded or not (except for normalization operations
like
s/\s+/ /g, which tend to be applied as in-place modifications rather than
assignments to a new scalar).

That's a huge exception, and /r finally made it so it was cleaner not to do
it in scalar context.

sub trim { $_[0] =~ s/^\s+//r =~ s/\s+\z//r }

My point is that /r wasn't a mistake, so let's not bring that into the
discussion.

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

No branches or pull requests

2 participants