How can I play this Perl routine that does the replacement?

I have the following routine in Perl to replace "abc" with "xyz" in a line:

sub mySubst { my ($str) = @_; $str =~ s|abc|xyz|ig; return $str; } 

It works, but it looks too much for Perl. How can i tighten it?

+4
source share
9 answers

Here's how I could make this subroutine more idiomatic:

 sub mySubst { (my $str = shift) =~ s|abc|xyz|ig; return $str; } 
+3
source

Are you alright.

  • You pull the arguments from the @_ variable, making a copy using the list assignment. List assignment is a great way to do this (and basically a standard way.) Using shift will also work, but @_ changes (may or may not be what you want). This discusses the PerlMonks vs @_ change issue that might interest you.
  • You use a named variable with your search and replace. I prefer named variables in this case, since Perl magic variable handling will take care.
  • Automatic work on $ _ would be possible, but in the absence of autocompletion of $ _, this becomes a more difficult task. You will need to do local $_ = shift; or local ($_) = @_; which doesn't add much.)
  • I like when people use explicit return . It is warm fuzzy.
  • K & R Brackets. Good.:)
  • There is no prototype. Excellent.:)

Go with him. I think you're on the right track.

+8
source

If you are looking for golf and no production code.

 use strict; ## Not really required ;) use warnings; ## Not really required ;) sub f{local$_=pop,s/foo/bar/ig;$_} print f 'foobarbaz'; 
+6
source

You can write:

 sub mySubst { (map { s|abc|xyz|ig; $_ } "$_[0]" )[0] } 

but if this is not an exercise in obfuscation, I would say go with what you have. Remember that you are not writing a program for a computer.

+3
source

I think the words are too verbose, such as insufficient obfuscation, which I disagree with. As for tightening, I would suggest something like:

 sub replaceBeginningWithEnd { my $text = shift; return if not defined($text); $text =~ s/abc/xyz/ig; return $text; } 
  • Make names more readable
  • Use conventions (i.e. / as contrast |)
  • Checking Arguments
+1
source

No one has yet given the Perl idiom for this. This repeats the behavior of the source code by modifying the copy:

  (my $new_str = $old_str) =~ s/abc/xyz/ig; 

If I had to put this in a routine, which, in my opinion, is stupid for such a simple operation, I assume that it would be:

  sub foo { (my $s = $_[0]) =~ s/abc/xyz/ig; $s } 

However, if I did something stupid, I would not have made a subheading for him. I would do a subroutine to make a subroutine for me, so I don't need a new named subsection for all possible notes:

  sub make_sub { my( $regex, $replacement ) = @_; # season to taste with error checking sub { (my $s = $_[0]) =~ s/$regex/$replacement/ig; $s }; } my $replacer = make_sub( qr/abc/, 'xyz' ); my $new = $replacer->( $string ); 
+1
source

Why do I need to sign? just do it like that

 $str =~ s|abc|xyz|ig; 
0
source

You can omit the return keyword:

 sub mySubst { my ($str) = @_; $str =~ s|abc|xyz|ig; $str; } 

You can also use the default variable ( $_ ):

 sub mySubst { local $_ = shift; # or my starting from Perl 5.10 s|abc|xyz|ig; $_; } 
0
source

To avoid changing the originals, you can write

 sub mySubst { map { (my $s=$_) =~ s|abc|xyz|ig; $s } @_ } 

or

 sub mySubst { my @a = @_; map { s|abc|xyz|ig; $_ } @a } 

or borrow an answer from Sinan, except that it explicitly discards the temporary array:

 sub mySubst { map { s|abc|xyz|ig; $_ } my(undef) = @_ } 

but the syntax is still a bit noisy. Since it uses map , be sure to call it in the context of the list:

 my($result) = mySubst $str; # NOT my $one = mySubst $str; 

If you usually call mySubst with a single argument, but want to handle cases of one or more arguments, you can write

 sub mySubst { s|abc|xyz|ig for my @a = @_; wantarray ? @a : $a[0]; } 

but it will start stuttering again.


If you want to update the parameter itself, use the semantics of Perl subset aliases, as described in perlsub :

The @_ array is a local array, but its elements are aliases for real scalar parameters. In particular, if the element $_[0] updated, the corresponding argument is updated (or an error occurs if it is not updated).

So you can write

 sub mySubst { $_[0] =~ s|abc|xyz|ig } 

or even

 sub mySubst { map { s|abc|xyz|ig; $_ } @_ } 

Usage example:

 $str = "fooabcbar"; mySubst $str; print $str, "\n"; 

Conclusion:

  fooxyzbar 
0
source

Source: https://habr.com/ru/post/1301355/


All Articles