Perl Scope Confusion with Format / Write
Why is $var
unavailable (out of scope ?) to write
when declared with my
, if its scope is pretty much package-level ?
package ASDF;
use warnings;
use strict;
use feature 'say';
my $var = 'foo';
format =
@<<<<< @>>>>>
'test : ', $var
.
sub test {
say $var;
write;
}
1;
Called with :
perl -wE 'use ASDF; ASDF::test();'
Produces :
foo
Variable "$var" is not available at ASDF.pm line 16.
Use of uninitialized value $var in formline at ASDF.pm line 10.
test :
It appears otherwise available to say
in the same scope ...
Replacing my
with our
fixes it :
foo
test : foo
Why can't write
pick-up on $var
correctly ?
Is it a scope issue, or an issue with how Perl's write
or format
is implemented ?
perl scope built-in
|
show 4 more comments
Why is $var
unavailable (out of scope ?) to write
when declared with my
, if its scope is pretty much package-level ?
package ASDF;
use warnings;
use strict;
use feature 'say';
my $var = 'foo';
format =
@<<<<< @>>>>>
'test : ', $var
.
sub test {
say $var;
write;
}
1;
Called with :
perl -wE 'use ASDF; ASDF::test();'
Produces :
foo
Variable "$var" is not available at ASDF.pm line 16.
Use of uninitialized value $var in formline at ASDF.pm line 10.
test :
It appears otherwise available to say
in the same scope ...
Replacing my
with our
fixes it :
foo
test : foo
Why can't write
pick-up on $var
correctly ?
Is it a scope issue, or an issue with how Perl's write
or format
is implemented ?
perl scope built-in
3
Seems like formats don't properly close over lexical variables. This is the sort of error message I'd expect fromeval('$x')
where$x
is a variable from some surrounding lexical scope that isn't used in the subroutine otherwise.
– melpomene
Jan 2 at 18:37
Did you tryour $var
?
– toolic
Jan 2 at 18:41
2
@toolic "Replacingmy
withour
fixes it :"
– melpomene
Jan 2 at 18:43
2
I repeat: Perl6::Form is a module for Perl5
– ikegami
Jan 3 at 3:00
3
Formats are an ancient feature of Perl (older than local variables). My guess is no one has touched their code in 20 years. It looks like a bug to me.
– melpomene
Jan 3 at 12:25
|
show 4 more comments
Why is $var
unavailable (out of scope ?) to write
when declared with my
, if its scope is pretty much package-level ?
package ASDF;
use warnings;
use strict;
use feature 'say';
my $var = 'foo';
format =
@<<<<< @>>>>>
'test : ', $var
.
sub test {
say $var;
write;
}
1;
Called with :
perl -wE 'use ASDF; ASDF::test();'
Produces :
foo
Variable "$var" is not available at ASDF.pm line 16.
Use of uninitialized value $var in formline at ASDF.pm line 10.
test :
It appears otherwise available to say
in the same scope ...
Replacing my
with our
fixes it :
foo
test : foo
Why can't write
pick-up on $var
correctly ?
Is it a scope issue, or an issue with how Perl's write
or format
is implemented ?
perl scope built-in
Why is $var
unavailable (out of scope ?) to write
when declared with my
, if its scope is pretty much package-level ?
package ASDF;
use warnings;
use strict;
use feature 'say';
my $var = 'foo';
format =
@<<<<< @>>>>>
'test : ', $var
.
sub test {
say $var;
write;
}
1;
Called with :
perl -wE 'use ASDF; ASDF::test();'
Produces :
foo
Variable "$var" is not available at ASDF.pm line 16.
Use of uninitialized value $var in formline at ASDF.pm line 10.
test :
It appears otherwise available to say
in the same scope ...
Replacing my
with our
fixes it :
foo
test : foo
Why can't write
pick-up on $var
correctly ?
Is it a scope issue, or an issue with how Perl's write
or format
is implemented ?
perl scope built-in
perl scope built-in
asked Jan 2 at 18:23
robutrobut
427
427
3
Seems like formats don't properly close over lexical variables. This is the sort of error message I'd expect fromeval('$x')
where$x
is a variable from some surrounding lexical scope that isn't used in the subroutine otherwise.
– melpomene
Jan 2 at 18:37
Did you tryour $var
?
– toolic
Jan 2 at 18:41
2
@toolic "Replacingmy
withour
fixes it :"
– melpomene
Jan 2 at 18:43
2
I repeat: Perl6::Form is a module for Perl5
– ikegami
Jan 3 at 3:00
3
Formats are an ancient feature of Perl (older than local variables). My guess is no one has touched their code in 20 years. It looks like a bug to me.
– melpomene
Jan 3 at 12:25
|
show 4 more comments
3
Seems like formats don't properly close over lexical variables. This is the sort of error message I'd expect fromeval('$x')
where$x
is a variable from some surrounding lexical scope that isn't used in the subroutine otherwise.
– melpomene
Jan 2 at 18:37
Did you tryour $var
?
– toolic
Jan 2 at 18:41
2
@toolic "Replacingmy
withour
fixes it :"
– melpomene
Jan 2 at 18:43
2
I repeat: Perl6::Form is a module for Perl5
– ikegami
Jan 3 at 3:00
3
Formats are an ancient feature of Perl (older than local variables). My guess is no one has touched their code in 20 years. It looks like a bug to me.
– melpomene
Jan 3 at 12:25
3
3
Seems like formats don't properly close over lexical variables. This is the sort of error message I'd expect from
eval('$x')
where $x
is a variable from some surrounding lexical scope that isn't used in the subroutine otherwise.– melpomene
Jan 2 at 18:37
Seems like formats don't properly close over lexical variables. This is the sort of error message I'd expect from
eval('$x')
where $x
is a variable from some surrounding lexical scope that isn't used in the subroutine otherwise.– melpomene
Jan 2 at 18:37
Did you try
our $var
?– toolic
Jan 2 at 18:41
Did you try
our $var
?– toolic
Jan 2 at 18:41
2
2
@toolic "Replacing
my
with our
fixes it :"– melpomene
Jan 2 at 18:43
@toolic "Replacing
my
with our
fixes it :"– melpomene
Jan 2 at 18:43
2
2
I repeat: Perl6::Form is a module for Perl5
– ikegami
Jan 3 at 3:00
I repeat: Perl6::Form is a module for Perl5
– ikegami
Jan 3 at 3:00
3
3
Formats are an ancient feature of Perl (older than local variables). My guess is no one has touched their code in 20 years. It looks like a bug to me.
– melpomene
Jan 3 at 12:25
Formats are an ancient feature of Perl (older than local variables). My guess is no one has touched their code in 20 years. It looks like a bug to me.
– melpomene
Jan 3 at 12:25
|
show 4 more comments
1 Answer
1
active
oldest
votes
At the bottom of the Perl format documentation it says:
Lexical variables (declared with "my") are not visible within a format unless the format is declared within the scope of the lexical variable.
Reading that would imply that what you are trying would work, but apparently lexically scoped variables work differently for format
and write
when called from outside of the package they where declared in. Also, all of the examples in the article use global variables...
This more modern tutorial about format repeats that you might run into trouble if you use lexically scoped variables (variables declared with my
) because write picks the variables from the current package and, as stated in the comments of your question, was written in a time when Perl did not have the my
keyword or lexical scoping.
The solutions the article offers:
When you are ready to output some data, you use write. This design shows the age of formats since write doesn't take arguments to fill in the pictures. It uses the variables that are in scope.
our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();
Formats are also a bit crufty because you don't pass arguments to write to fill in the pictures. Perl relies on variables with the specified names being in scope. You can use lexical variables, but they have to be in the same scope as the format definition, and they have to be in scope when you call write. It's impractical to do that with lexicals, so the most agile way involves localized package variables:
foreach my $record ( @cats ) {
local( $id, $name, $food ) = @$record;
write( $fh );
}
And also this advice in the wrap-up:
- Use localized package variables to set data for the format
So, our
and local
seem to be the way to go if you want to keep using format
and write
in modern Perl.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011306%2fperl-scope-confusion-with-format-write%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
At the bottom of the Perl format documentation it says:
Lexical variables (declared with "my") are not visible within a format unless the format is declared within the scope of the lexical variable.
Reading that would imply that what you are trying would work, but apparently lexically scoped variables work differently for format
and write
when called from outside of the package they where declared in. Also, all of the examples in the article use global variables...
This more modern tutorial about format repeats that you might run into trouble if you use lexically scoped variables (variables declared with my
) because write picks the variables from the current package and, as stated in the comments of your question, was written in a time when Perl did not have the my
keyword or lexical scoping.
The solutions the article offers:
When you are ready to output some data, you use write. This design shows the age of formats since write doesn't take arguments to fill in the pictures. It uses the variables that are in scope.
our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();
Formats are also a bit crufty because you don't pass arguments to write to fill in the pictures. Perl relies on variables with the specified names being in scope. You can use lexical variables, but they have to be in the same scope as the format definition, and they have to be in scope when you call write. It's impractical to do that with lexicals, so the most agile way involves localized package variables:
foreach my $record ( @cats ) {
local( $id, $name, $food ) = @$record;
write( $fh );
}
And also this advice in the wrap-up:
- Use localized package variables to set data for the format
So, our
and local
seem to be the way to go if you want to keep using format
and write
in modern Perl.
add a comment |
At the bottom of the Perl format documentation it says:
Lexical variables (declared with "my") are not visible within a format unless the format is declared within the scope of the lexical variable.
Reading that would imply that what you are trying would work, but apparently lexically scoped variables work differently for format
and write
when called from outside of the package they where declared in. Also, all of the examples in the article use global variables...
This more modern tutorial about format repeats that you might run into trouble if you use lexically scoped variables (variables declared with my
) because write picks the variables from the current package and, as stated in the comments of your question, was written in a time when Perl did not have the my
keyword or lexical scoping.
The solutions the article offers:
When you are ready to output some data, you use write. This design shows the age of formats since write doesn't take arguments to fill in the pictures. It uses the variables that are in scope.
our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();
Formats are also a bit crufty because you don't pass arguments to write to fill in the pictures. Perl relies on variables with the specified names being in scope. You can use lexical variables, but they have to be in the same scope as the format definition, and they have to be in scope when you call write. It's impractical to do that with lexicals, so the most agile way involves localized package variables:
foreach my $record ( @cats ) {
local( $id, $name, $food ) = @$record;
write( $fh );
}
And also this advice in the wrap-up:
- Use localized package variables to set data for the format
So, our
and local
seem to be the way to go if you want to keep using format
and write
in modern Perl.
add a comment |
At the bottom of the Perl format documentation it says:
Lexical variables (declared with "my") are not visible within a format unless the format is declared within the scope of the lexical variable.
Reading that would imply that what you are trying would work, but apparently lexically scoped variables work differently for format
and write
when called from outside of the package they where declared in. Also, all of the examples in the article use global variables...
This more modern tutorial about format repeats that you might run into trouble if you use lexically scoped variables (variables declared with my
) because write picks the variables from the current package and, as stated in the comments of your question, was written in a time when Perl did not have the my
keyword or lexical scoping.
The solutions the article offers:
When you are ready to output some data, you use write. This design shows the age of formats since write doesn't take arguments to fill in the pictures. It uses the variables that are in scope.
our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();
Formats are also a bit crufty because you don't pass arguments to write to fill in the pictures. Perl relies on variables with the specified names being in scope. You can use lexical variables, but they have to be in the same scope as the format definition, and they have to be in scope when you call write. It's impractical to do that with lexicals, so the most agile way involves localized package variables:
foreach my $record ( @cats ) {
local( $id, $name, $food ) = @$record;
write( $fh );
}
And also this advice in the wrap-up:
- Use localized package variables to set data for the format
So, our
and local
seem to be the way to go if you want to keep using format
and write
in modern Perl.
At the bottom of the Perl format documentation it says:
Lexical variables (declared with "my") are not visible within a format unless the format is declared within the scope of the lexical variable.
Reading that would imply that what you are trying would work, but apparently lexically scoped variables work differently for format
and write
when called from outside of the package they where declared in. Also, all of the examples in the article use global variables...
This more modern tutorial about format repeats that you might run into trouble if you use lexically scoped variables (variables declared with my
) because write picks the variables from the current package and, as stated in the comments of your question, was written in a time when Perl did not have the my
keyword or lexical scoping.
The solutions the article offers:
When you are ready to output some data, you use write. This design shows the age of formats since write doesn't take arguments to fill in the pictures. It uses the variables that are in scope.
our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();
Formats are also a bit crufty because you don't pass arguments to write to fill in the pictures. Perl relies on variables with the specified names being in scope. You can use lexical variables, but they have to be in the same scope as the format definition, and they have to be in scope when you call write. It's impractical to do that with lexicals, so the most agile way involves localized package variables:
foreach my $record ( @cats ) {
local( $id, $name, $food ) = @$record;
write( $fh );
}
And also this advice in the wrap-up:
- Use localized package variables to set data for the format
So, our
and local
seem to be the way to go if you want to keep using format
and write
in modern Perl.
edited Jan 30 at 7:59
answered Jan 30 at 7:46
PowertiekePowertieke
1,92011118
1,92011118
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011306%2fperl-scope-confusion-with-format-write%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
Seems like formats don't properly close over lexical variables. This is the sort of error message I'd expect from
eval('$x')
where$x
is a variable from some surrounding lexical scope that isn't used in the subroutine otherwise.– melpomene
Jan 2 at 18:37
Did you try
our $var
?– toolic
Jan 2 at 18:41
2
@toolic "Replacing
my
withour
fixes it :"– melpomene
Jan 2 at 18:43
2
I repeat: Perl6::Form is a module for Perl5
– ikegami
Jan 3 at 3:00
3
Formats are an ancient feature of Perl (older than local variables). My guess is no one has touched their code in 20 years. It looks like a bug to me.
– melpomene
Jan 3 at 12:25