zsh: How to control variable scope in sourced files?
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Shell > zsh: How to control variable scope in sourced files?




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    zsh: How to control variable scope in sourced files?  
kj


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-22-06 11:10 PM






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.





[ Post a follow-up to this message ]



    Re: zsh: How to control variable scope in sourced files?  
Stephane CHAZELAS


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-23-06 07: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





[ Post a follow-up to this message ]



    Re: zsh: How to control variable scope in sourced files?  
kj


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-23-06 11:13 PM

In <slrndt93hm.4qc.stephane.chazelas@spam.is.invalid> Stephane CHAZELAS <thi
s.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.





[ Post a follow-up to this message ]



    Re: zsh: How to control variable scope in sourced files?  
Stephane Chazelas


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-23-06 11: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





[ Post a follow-up to this message ]



    Re: zsh: How to control variable scope in sourced files?  
kj


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-23-06 11:13 PM

In <slrndt9tis.sq3.stephane_chazelas@duey.spider.com> Stephane Chazelas <ste
phane_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.





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 09:18 PM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register