sat
sat

Reputation: 14949

difference between my and our ? (declared in the same file)

Before writing this program,I thought that our is a package scope variable and my is a file scope variable.But,After did that program,I am get confused.

My program is,

#!/usr/bin/perl

use strict;
use warnings;

package one; 
our $val = "sat";
my $new = "hello";
print "ONE:val =>$val \n";
print "ONE:new =>$new \n\n";

package two;
print "TWO:val =>$val \n";
print "TWO:new =>$new \n";

which outputs

ONE:val =>sat 
ONE:new =>hello 

TWO:val =>sat 
TWO:new =>hello 

So,what is the difference between my and our.Whether the both are the same or it having any difference?

Upvotes: 13

Views: 3340

Answers (3)

aleroot
aleroot

Reputation: 72636

my restrict the variables access to the innermost block in which they were declared. If there is no block, they are file-scoped.

our instead associates a simple name with a package variable in the current package , so it is declared at the package level and linked to the package name. our tries to help out by letting you use package variables without adding the package name.

package pack;
our $variable;    # These are the same
$pack::variable;  # These are the same

An our variable is something similar to C's static variable, but is different because the variable declared with our in a function is still accessible outside the function if it is called with the variable's fully qualified name.

But most of all my is lexically scoped while our is lexical scope but their life persistent even outside the declaring block(their life is like global variable life), therefore to really understand the difference between my and our you have to understand the difference between lexically and global scoped in Perl.

So briefly the difference between the two type are :

Global variables

Any code, anywhere, can change their values.

Lexical variables

The life of the variable end with the the end of the code block in with they are included, after that their values are garbage collected. These kind of variables can be accessed only within the block in which they are declared.


To answer you specific example-question : try to move the second package declaration (package two) into another file, and you will see the difference between my and our ...

Upvotes: 6

Borodin
Borodin

Reputation: 126722

It is important to distinguish between visibility and lifetime.

The visibility of variables declared using our or my is identical. You can used the name anywhere after the declaration before the first enclosing brace or end of file.

Beware that this doesn't apply to full-qualified variable names, which need no declaration and can be accessed anywhere. Without declaring anything I can assign to a package variable

$pack::three = 3;

and use that anywhere else in any package. I don't even have to declare the pack package. But if I write

package pack;
our $three;

I have generated an shortened alias for $pack::three that I can use within the same lexical scope as I could a my variable in the same place: before an enclosing brace or end of file.

These package variables are always available from the start of the program's execution. Just like hash elements you can always assign to a new one and it will always be there - their lifetime is endless. In fact package variables are hash elements to all intents and purposes.

Lexical variables, declared with my, on the other hand, are created at the point of declaration and destroyed once they go out of scope and there is no reference to them held anywhere. So, unless you take the reference of such a variable, its lifetime is the same as its visibility. A my declaration inside a loop causes a new variable to be created and destroyed for each execution the loop.

In your code, you have created an alias $val for package variable $one::val and a lexical variable $new. Neither are within a code block so both are visible to the end of the file. The package two has no effect at all here, but if you had written our $val after that second package statement you would have changed the alias $val to indicate $two::val instead.

I hope that helps.

Upvotes: 3

tchrist
tchrist

Reputation: 80384

As you see, both my and our have lexical effect.

my creates a lexically scoped variable.

our creates a lexically scoped alias to a package variable.

Just because you say package in no fashion changes the lexical scope, so your $val is still an alias to $one::val even after having seen the package two statement.

If you don’t see a close curly, you haven’t finished your scope. (Or EOF or end of string in a string eval).

Upvotes: 20

Related Questions