|
Home > Archive > Unix Shell > January 2006 > zsh: How to control variable scope in sourced files?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
zsh: How to control variable scope in sourced files?
|
|
|
|
I have an "aliases" file that is sourced at start up. As the name
suggests, this file defines various aliases and functions.
I would like to define some variables that have the rest of the
file as their "lexical scope", shadowing preexisting variables if
necessary. For example, if I define, within this file, the variables
FOO=1 and BAR=2, and then define the function
demo () {
echo foo: $FOO
echo bar: $BAR
}
then I should be able to do this:
% BAR=100
% source aliases
% demo
foo: 1
bar: 2
% echo $FOO # FOO is undefined now
% echo $BAR # BAR retains pre-existing value
100
Notice that the demo function still uses the value of BAR defined
within the aliases file, but this value does not affect the value
of the BAR variable defined outside of the file.
Is it possible to do this with a zsh script?
Thanks!
kj
--
NOTE: In my address everything before the first period is backwards;
and the last period, and everything after it, should be discarded.
| |
| Stephane CHAZELAS 2006-01-23, 2:55 am |
| 2006-01-21, 17:56(+00), kj:
>
>
>
>
>
> I have an "aliases" file that is sourced at start up. As the name
> suggests, this file defines various aliases and functions.
>
> I would like to define some variables that have the rest of the
> file as their "lexical scope", shadowing preexisting variables if
> necessary. For example, if I define, within this file, the variables
> FOO=1 and BAR=2, and then define the function
>
> demo () {
> echo foo: $FOO
> echo bar: $BAR
> }
>
> then I should be able to do this:
>
> % BAR=100
> % source aliases
> % demo
> foo: 1
> bar: 2
> % echo $FOO # FOO is undefined now
>
> % echo $BAR # BAR retains pre-existing value
> 100
>
> Notice that the demo function still uses the value of BAR defined
> within the aliases file, but this value does not affect the value
> of the BAR variable defined outside of the file.
>
> Is it possible to do this with a zsh script?
[...]
Only function and subshells can affect the scope. So use
functions for instance.
aliases.zsh:
<<
demo() {
print -r -- $BAR
...
}
main() {
local FOO BAR
BAR=200
alias whatever=...
}
main[vbcol=seagreen]
BAR=100
source aliases.zsh
demo
--
Stéphane
| |
|
| In <slrndt93hm.4qc.stephane.chazelas@spam.is.invalid> Stephane CHAZELAS <this.address@is.invalid> writes:
>2006-01-21, 17:56(+00), kj:
>[...]
>Only function and subshells can affect the scope. So use
>functions for instance.
>aliases.zsh:
><<
>demo() {
> print -r -- $BAR
> ...
>}
>main() {
> local FOO BAR
> BAR=200
> alias whatever=...
>}
>main
[vbcol=seagreen]
>BAR=100
>source aliases.zsh
>demo
Thanks, but that doesn't do what I want to do. The following
illustrates my intent better (but still it doesn't work!):
<<
main() {
local BAR
BAR=200
demo() {
print -r -- $BAR
}
}
main
unfunction main[vbcol=seagreen]
Now if I do
% BAR=100
% source aliases.zsh
% demo
100
That output is not what I want. I want 200, i.e. the value that
BAR had in the lexical scope in which demo was defined. It sounds
like this is not possible (without rolling out something like
Perl)...
kj
--
NOTE: In my address everything before the first period is backwards;
and the last period, and everything after it, should be discarded.
| |
| Stephane Chazelas 2006-01-23, 6:13 pm |
| On Mon, 23 Jan 2006 14:00:40 +0000 (UTC), kj wrote:
[...]
> main() {
> local BAR
> BAR=200
> demo() {
> print -r -- $BAR
> }
> }
>
> main
> unfunction main
>
> Now if I do
>
> % BAR=100
> % source aliases.zsh
> % demo
> 100
>
> That output is not what I want. I want 200, i.e. the value that
> BAR had in the lexical scope in which demo was defined. It sounds
> like this is not possible (without rolling out something like
> Perl)...
[...]
That would not make any sense at all.
Executing
f() {
code
}
stores the "code" in memory to be executed for further
invocation of f. There's only one storage area for functions,
when main is finished, its local variable "scope" storing area
is gone. I can't see what you would expect here.
You can expand BAR at the time you execute the definition of the
function for instance. Something like:
main() {
local BAR
BAR=200
eval "
demo() {
local BAR
BAR=${(q)BAR} # expanded with quoting"'
print -r -- $BAR
}
'
}
main
unfunction main
which demo
--
Stephane
| |
|
| In <slrndt9tis.sq3.stephane_chazelas@duey.spider.com> Stephane Chazelas <stephane_chazelas@yahoo.fr> writes:
>On Mon, 23 Jan 2006 14:00:40 +0000 (UTC), kj wrote:
>[...]
>
>[...]
>That would not make any sense at all.
>Executing
>f() {
> code
>}
>stores the "code" in memory to be executed for further
>invocation of f. There's only one storage area for functions,
>when main is finished, its local variable "scope" storing area
>is gone. I can't see what you would expect here.
What I'm trying to do is pretty standard in Perl, where it usually
comes under the heading "closures". E.g. the following PERL script
prints out
200
100
<<
my $BAR = 100;
sub main {
my $BAR = 200;
sub demo {
print "$BAR\n";
}
}
main();
demo();
print "$BAR\n";[vbcol=seagreen]
....though, admittedly, this is very weird-looking Perl. A more
idiomatic version would dispense with main() altogether:
<<
my $BAR = 100;
{
my $BAR = 200;
sub demo {
print $BAR;
}
}
demo();
print "$BAR\n";[vbcol=seagreen]
The $BAR in demo() "remembers" the value it had in the scope where
demo() is defined.
The eval approach you suggested seems like the way to go if I stick
with zsh for this.
Thanks!
kj
--
NOTE: In my address everything before the first period is backwards;
and the last period, and everything after it, should be discarded.
|
|
|
|
|