3 ms·
The the distinction in Perl is context. If I want to flatten that pack of dogs into a collection of individual dogs, I'd use the `@` sigil. If I want to opera
by daotoad 6y ago
The the distinction in Perl is context. If I want to flatten that pack of dogs into a collection of individual dogs, I'd use the `@` sigil. If I want to operate on the pack as a whole, I'd use the `$`.
Context and list flattening are probably the most foreign parts of Perl to someone who doesn't know it. Everyone fixates on the sigils, but the weirdness in the way sigils operate stems from context.
When you call a function, the arguments are flattened into a single list. So `foo(1,2)` is the same as `my @args = (1,2,3); foo(@args, 3)`. Every expression can be evaluated in one or more contexts. So taking the value of an array in scalar context gives you the length, which is handy but also means that, since 0 is falsy, you can just do logical tests on arrays to check if they are empty. Because the behaviors are relatively intuitive, it's possible to quite a bit of work in Perl before you even understand what context is or how it operates. `if (@foo) { do_stuff(@foo) }` does what you'd think it does, even if you don't know about context.
But it also means that the distinction between `my $match = $foo=~/(foo)/g;` and `my ($match) = $foo=~/(foo)/g;` is not at all obvious if you don't understand context. (The first example gives you the count of matches, the second example gives you the first match because the parens put you in a list context which means you are effectively assigning into a slice.)