Forcing a scalar

#!/usr/bin/perl use Modern::Perl; while (<>) { chomp; say reverse; } 

The above code does not work, but when I change the second last line to say scalar reverse; then it works fine. Why do I need to make it be a scalar explicitly? Can't Perl DWIM?

+6
source share
2 answers

If I understand the documentation correctly, reverse usually works with lists. In the context of a list used without arguments, it returns an empty list and by default does not assign it anywhere. In your example, let's say it displays unchanged $_ ;

Forcing reverse into a scalar context changes its behavior and makes it back to character strings and uses $_ by default. Since say can be used to print lists, as well as for scalars, it does not force its arguments in a scalar context.

Perl probably does DWIM only for the given "I" values.

A breakdown of what the converse does when:

 #!/usr/bin/env perl use strict; use v5.12; my $inscalar = "foo bar"; # `reverse` is in list context, $in is coerced to a single-element list my @outlist = reverse $inscalar; # `reverse` is in scalar context, so it reverses strings my $outscalar = reverse $inscalar; say join(" | ", @outlist); # prints "foo bar" say $outscalar; # prints "rab oof" # the "normal" behaviour of `reverse` my @inlist = qw(foo bar); @outlist = reverse @inlist; say join(" | ", @outlist); # prints "bar | foo" 
+6
source
Why do I need to make it be a scalar explicitly?

Like documented , reverse reverses the order of the elements in the argument list when used in the context of the list. For example, reverse 'a', 'b', 'c' returns 'c', 'b', 'a' .

Can't Perl DWIM?

Yes, it could do what you want (scalar behavior when there is no argument expression).

However, this can be confusing. I can’t think of any other operator that changes behavior based on the absence of an argument expression (as opposed to simply the absence of arguments).
+3
source

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


All Articles