What is the difference between -> and :: in Perl

后端 未结 3 1663
北荒
北荒 2021-02-05 05:44

What is the exact difference between :: and -> in Perl?

-> sometimes works where :: does not.

3条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-05 06:07

    :: has two uses.

    1. It's the namespace separator in package names

      use Foo::Bar;    # Load Foo/Bar.pm
      $Foo::Bar::var   # $var in namespace Foo::Bar
      
    2. Appended to a bareword, it creates a string literal[1].

      The following is the same as 'hello' except it warns if the package hello doesn't exist:

      hello::
      

    -> has two uses.

    1. It's used to dereference.

      $array_ref->[$i]
      $hash_ref->{$k}
      $code_ref->(@args)
      
    2. It's used in method calls to denote the invocant.

      CGI->new()        # Static method call
      $cgi->param()     # Object method call
      

    You're probably asking what's the difference between

    Foo::Bar::mysub()
    

    and

    Foo::Bar->mysub()
    

    The former is a function call. The latter is a method call. A method call is like a function call with two differences:

    1. Method calls use inheritance.

    2. Method calls pass the invocant (what's left of the ->) to the sub as its first argument.

    {
       package Foo::Baz;
       sub new {
          my ($class, $arg) = @_;
          my $self = bless({}, $class);
          $self->{arg} = $arg;
          return $self;
       }
    
       sub mysub1 {
          my ($self) = @_;
          print($self->{arg}, "\n");
       }
    }
    
    {
       package Foo::Bar;
       our @ISA = 'Foo::Baz'; 
       sub mysub2 {
          my ($self) = @_;
          print(uc($self->{arg}), "\n");
       }
    }
    
    my $o = Foo::Bar->new('hi');  # Same as: my $o = Foo::Baz::new('Foo::Bar', 'hi');
    $o->mysub1();                 # Same as: Foo::Baz::mysub1($o);
    $o->mysub2();                 # Same as: Foo::Bar::mysub2($o);
    

    Notes

    1. Foo->method deceptively calls the sub named Foo if it exists (using its the value it returns as the invocant). Foo::->method, meaning 'Foo'->method, doesn't.

提交回复
热议问题