moby
moby

Reputation: 149

Perl Syntax characters "::"

I can't find anywhere what the :: is for in Perl. Example:

$someVariable::QUERY{'someString'};

Thanks!

Upvotes: 7

Views: 7135

Answers (4)

David W.
David W.

Reputation: 107040

It's covered in Perlmod.

The :: is really a namespace identifier. In early Perl before this idea of namespace took hold, you could have variable name collisions happening in your program:

Here's my program:

#! /usr/bin/env perl

#use strict;
use warnings;
use feature qw(say);

require "test2.pl";

$foo = "bar";

futz_with_foo();

say $foo;

I set $foo to bar and never touched it. Should print out bar However, when I run my program, I get:

$ ./test.pl
WOO WOO! I MESSED WITH FOO!

In test2.pl, I have:

sub futz_with_foo {
    $foo = "WOO WOO! I MESSED WITH FOO!"
}
1;

What happened is that both programs are using the same variable $foo. To get around this issue Perl gives modules the ability to have their own namespace. The original syntax was the single quote, but changed to :: in Perl 4 (if I remember correctly). You can still use the single quote. You declare your namespace with the package.

The best way to understand this is to see it in action. Try the following:

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);

our $foo = 'This is the value of $foo';

say '$foo: ' . $foo;
say '$main::foo: ' . $main::foo;
say "\$main'foo: " . $main'foo;;

say "\nSwitching to package Bar";
package Bar;

our $foo = 'This is in package Bar';

say '$foo: ' . $foo;
say '$Bar::foo: ' . $Bar::foo;

say "\nSwitching to package main again";
package main;

say '$foo: ' . $foo;

Running this, I get:

$foo: This is the value of $foo
$main::foo: This is the value of $foo
$main'foo: This is the value of $foo

Switching to package Bar
$foo: This is in package Bar
$Bar::foo: This is in package Bar

Switching to package main again
$foo: This is in package Bar

By default, your program starts out in the main namespace. By the way, you'll notice that I declared our $foo and not my $foo. That's because our puts the variable in the Perl symbol table where package variables are stored. The my is a lexically scoped declaration, and is now preferred. A variable declared with my only exists in its declared scope and that can't be outside of the file its in.

Maybe this will shed some light on the error message you get when you forget to declare a variable with my:

Global symbol "$foo" requires explicit package name at ...

By default, all Perl variables are Package variables (that is, they're in Perl's symbol table). The use strict pragma forces you to either declare package variables with our or forces you to use the full package name of the variable. By declaring a variable with my (like we do 99 40/100% of the time) and by using strict, we force you to declare your variables when using Perl.

Hope this helps.

Upvotes: 8

ikegami
ikegami

Reputation: 385655

It's not anything on its own. SomePackage::SomeHash as a whole is an identifier. $someVariable::QUERY{'someString'} refers to hash element someString of the hash %someVariable::QUERY. Hash %someVariable::QUERY is the full name of the hash %QUERY in the package someVariable.

Upvotes: 2

Joel Berger
Joel Berger

Reputation: 20280

These are package separators. I suspect the actual code is more like $SomePackage::SomeHash{'SomeKey'}. This syntax allows accessing a "package variable", in this case a hash, from some other package, or by its fully qualified name. You are probably more accustomed to seeing something like:

package SomePackage; 
our %SomeHash; 
$SomeHash{'SomeKey'} # do something with $SomePackage::SomeHash{'SomeKey'} here

A use case is setting up some module, like say Data::Dumper, which uses these package variables to control output:

use Data::Dumper;
local $Data::Dumper::Sortkeys = 1;
print Dumper { c => 3, a => 1, b => 2 };

... though this type of usage is typically avoided by using Object Oriented style.

See also: the famous "Coping with Scoping" article by MJD: http://perl.plover.com/FAQs/Namespaces.html

Upvotes: 12

IanPudney
IanPudney

Reputation: 6021

The double-colon operator :: is the separator used to prefix a member of a package, module, or class with the package, module, or class that the member is form (to distinguish between similarly named methods in different containers). You can visit this page for more information.

Upvotes: 3

Related Questions