Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

perl

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

-> sometimes works where :: does not.

like image 654
user2925716 Avatar asked Oct 27 '13 18:10

user2925716


People also ask

What does -> mean in Perl?

The arrow operator ( -> ) is an infix operator that dereferences a variable or a method from an object or a class. The operator has associativity that runs from left to right.

What is difference between and in Perl?

$ is for scalar variables(in your case a string variable.) @ is for arrays.

What is my in Perl?

my keyword in Perl declares the listed variable to be local to the enclosing block in which it is defined. The purpose of my is to define static scoping. This can be used to use the same variable name multiple times but with different values.


2 Answers

:: 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.
like image 68
ikegami Avatar answered Oct 21 '22 15:10

ikegami


When the right hand side is a function -> passes its left hand side as the first argument to the function. So the following examples are equivalent if $foo is an object blessed to package Foo and Bar is in package Foo. -> will resolve inherited methods making it cleaner and more useful for objects.

$foo->Bar();

Foo::Bar($foo);

-> can also take a package name

Foo->Bar();

Foo::Bar('Foo');

This means that -> is generally used in instance methods so that the object is passed its self and constructors so the constructors know which package to bless with. This is usually a parameter so it can be inherited.

like image 7
user1937198 Avatar answered Oct 21 '22 16:10

user1937198