Search code examples
perlsquare-bracketcurly-brackets

rules (?) of parens/brackets usage in perl


Did some search but couldn't find anything useful. I was wondering if there is a summary table of sort for beginners to learn about the "rules" of using parens/brackets, specifically, the differences among (), [], {}. Unfortunately, in my experience, use strict and use warnings don't tell me if I use the wrong parens.

For example, below are the legit codes (b/c they came from ikegami).

@{"genotype".($i)}
@{$genotype[$i]}
$genotype[$i] = [ split (/:/, $original_line[$i])]
my @genotype = map {[split /:/]} @original_line[6..14]

But are these below also legit ? Often times it's hard enough (for me) to know if it's other parts (logic) of the codes that cause the problem. Sorting through parens to me (a beginner) seems trivial to good coding. Any guide on how to properly use parens will be great.

@{"genotype".[$i]}
@["genotype".($i)]
@("genotype".($i))
@{$genotype($i)}
@[$genotype($i)]
$genotypes[$i] = ( split (/:/, $original_line[$i]))
my @genotype = map ([split /:/]) @original_line[6..14]

Solution

  • In Perl, brackets, braces and parens all have multiple meanings, but curly braces probably have the most.

    • Parens
      • Sort out precedence 2 * 3 + 4 vs. 2 * (3 + 4).
        • Delimiting argument lists for functions is a subcase of this: join "", 1, 2, 3 vs. join("", 1, 2), 3
        • Surround argument list of method call with arrow operator: $foo->bar(1, 2) (not needed for empty arglist)
      • Force interpretation of the previous bareword as a subroutine call. Compare Foo->new and Foo()->new.
      • Invoke coderefs with arrow operator: $code->()
      • Subroutine prototypes sub foo ($$;$%) { ... }
    • Square Brackets
      • Array subscript operator my @array = 1 .. 5; $array[1]
      • Arrayref literals my $aref = [1 .. 5]
    • Curly braces
      • Blocks (for do, sub, map, grep, conditionals, looping constructs, bare blocks, labeled blocks, ... )
      • Hash subscript operator $hash{foo}
      • Hashref literal my $hashref = { a => 3, b => 2 }
      • Dative block print { $filehandles[5] } "Hello world"
      • Circumfix dereference operators @{ $aref }, %{ $hashref }, ...
      • package blocks package Foo { ... }

    … and nearly all characters can be used as delimiters for quote-like operators q//, qq//, qr//, qx//, m//, s///, tr///, y///, leading to interesting stuff like s(foo){bar}g


    @{"genotype".($i)} uses curlies for symbolic dereferencing, and parens to (unneccessarily) sort out precedence.

    @{$genotype[$i]} uses brackets as array subscript operator, and curlies for dereferencing

    $genotype[$i] = [ split (/:/, $original_line[$i])] has various parts: $genotype[$i] and $original_line[$i] use brackets for array subscripting. The = [ ... ] uses brackets to make an anonymous arrayref. The parens in split(/:/, ...) just delimit the argument list for split (sorting out the precedence).

    my @genotype = map {[split /:/]} @original_line[6..14] uses brackets as the array subscript operator in @original_line[6..14], and for an anonymous array in [split /:/]. The curlies are used to form a block as first argument to map.