What does `my' do?!

F

Frank Seitz

Willem said:
Tim McDaniel wrote:
) That looks to me more like a scope compile-time effect. "my $x"
) creates a variable that doesn't come into rvalue scope until after the
) end of the statement, except that it can be assigned to in the
) statement itself. (It has two different scopes? Uglier and uglier.)

Indeed. Very annoying if you want to do something like:

my $widget = $main->SomeWidget(-command => sub {
...
$widget->insert($text);
...
});

Which doesn't work (obviously, after reading the above).

The scope of a lexical (my) variable begins AFTER the expression in which
it is declared, NOT inside the expression.

Maybe this is annoying, but the rule is simple.
I don't see any "ugliness".

Frank
 
T

Tim McDaniel

The scope of a lexical (my) variable begins AFTER the expression in
which it is declared, NOT inside the expression.

I've seen that statement before, but it now seems unclear to me. If
it were strictly and completely true, I don't see how you could assign
to a variable in a "my" -- because I use "scope of a variable" to mean
(roughly) "for an instance of $x, the places where $x refers to the
instance". For example, in

my $x = 1;

the new $x has to be assigned to for the statement to work, so I
interpret it that $x has to be in scope as an lvalue before the "="
(and therefore not "AFTER the expression") so it can be assigned to.
For a sillier distinguishing example,

my $x = $x;

as I see it, the new $x is not in the scope of the right-hand side but
IS in scope on the left-hand side.
 
B

Bo Lindbergh

I don't really know why it was implemented like that in the first place,

To make Lisp programmers feel at home? Compare:

(let ((x x)
(y y))
...whatever...)

and contrast:

{
my($x,$y)=($x,$y);
...whatever...
}


/Bo Lindbergh
 
F

Frank Seitz

Tim said:
The scope of a lexical (my) variable begins AFTER the expression in
which it is declared, NOT inside the expression.

I've seen that statement before, but it now seems unclear to me. If
it were strictly and completely true, I don't see how you could assign
to a variable in a "my" [...]

Okay, I try to be more precise:

STMT;

You can declare a lexical variable in STMT and - optionally -
assign a value to it, but nothing else. Within STMT you can't read it's value,
nor can you (re-)assign another value. The (real?) scope of the
variable begins after STMT.

Example:

f(my $x = 1, ...); # it's not possible to access $x in ...
# <- the scope of $x begins here
$x += 99;

Frank
 
D

derykus

Quoth (e-mail address removed):







You can assign to a variable that isn't in scope; for example,

    my $rv = do { \my $x };
    $$rv = 4;

The name $x has gone out of scope by the time the second statement
executes, but you can still assign to the variable it used to represent.
Similarly, one of the runtime effects of 'my' is that it returns (as an
lvalue) a variable that doesn't have a name in scope yet.




No, the name isn't in scope yet, even though the variable has been
created.

Ilya is right that this is very annoying, and could (should?) be
considered a bug in Perl. I don't really know why it was implemented
like that in the first place, though I can see it's obviously not going
to change now.

In the case of 'my $x = $x', wouldn't that be
somewhat confusing though...?

At least with current semantics, you could
do something that'd be arguably clearer
about the intent, eg:

my $x = 'what if";
{(my $x = $x) =~ s/what/then/;...}
 
I

Ilya Zakharevich

You can assign to a variable that isn't in scope;
No.

for example,

my $rv = do { \my $x };
$$rv = 4;

The name $x has gone out of scope by the time the second statement
executes, but you can still assign to the variable it used to represent.

No, you do not assign to a variable here. Any more than

shift()->{key} = 12;

assigns to a variable...
Similarly, one of the runtime effects of 'my' is that it returns (as an
lvalue) a variable that doesn't have a name in scope yet.

Yes, the (correct part of) this was the content of my previous
correction to (your?) message ;-). The incorrectness may be
"corrected" as

`my' returns an lvalue assignment to which modifies the same
container as "available in the future" variable

(if one would consider it as prose... :-[).
Ilya is right that this is very annoying, and could (should?) be
considered a bug in Perl. I don't really know why it was implemented
like that in the first place, though I can see it's obviously not going
to change now.

The *initial* intent (lost in the mist of centuries) was to be able to
"temporalize" changes by

local $foo = $foo;

`my' just behave symmetric to `local' - which was a very bad choice...

Yours,
Ilya
 
F

Frank Seitz

Ben said:
Quoth Frank Seitz said:
Tim said:
The scope of a lexical (my) variable begins AFTER the expression in
which it is declared, NOT inside the expression.
I've seen that statement before, but it now seems unclear to me. If
it were strictly and completely true, I don't see how you could assign
to a variable in a "my" [...]
Okay, I try to be more precise:

STMT;

You can declare a lexical variable in STMT and - optionally -
assign a value to it, but nothing else. Within STMT you can't read it's value,
nor can you (re-)assign another value. The (real?) scope of the
variable begins after STMT.

You just *know* I have to argue with that, don't you :)?

my $x;
$x = \(my $y = 3),
# $y isn't in scope yet
$$x = 4;
say $y;

gives '4'

Oh no! What a dirty trick! ;)
so you *can* assign to $y before the statement has ended. You
just can't use the *name* $y to refer to it, as the name isn't in scope
yet.
Names have different scopes from variables. [1] The scope of the name begins
at the end of the statement and ends at the end of the innermost
containing block. [2] The scope of the variable begins when the 'my'
expression is reached at runtime and ends when the last ref to it is
removed

What you describe is - in computer science terminology - the difference
between the scope and the lifetime of a variable: [1] is the definition
of the *scope* and [2] is the definition of the *lifetime* of a
lexical varibale in Perl. As we see, this distinction is important.
The concepts should not be confused with one another.
When I say "scope", I mean [1].
(it gets a temporary free pass for the remainder of its first
statement, otherwise it would immediately vanish (actually, it always
gets a free pass for the remainder of the statement in which it loses
all refs. Consider

use Scalar::Util qw/weaken/;

my $x = [4];
my $wr = $x;
weaken $wr;

$x = undef, my $y = $wr;

say $wr;

and then replace that , with a ; .)).

I understand what happens, I think. But I don't understand what
this has to do with the scope (or the lifetime) of the
variables $x, $y or $wr.

Frank
 
T

Tim McDaniel

The scope of the name begins at the end of the statement and ends at
the end of the innermost containing block

except where hidden by other "my" or "local" declarations within
that scope. Is that correct?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top