Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: values of associations pointed by P flag
- X-seq: zsh-workers 22459
- From: Peter Stephenson <pws@xxxxxxx>
- To: zsh-workers@xxxxxxxxxx (Zsh hackers list)
- Subject: Re: values of associations pointed by P flag
- Date: Thu, 25 May 2006 16:15:55 +0100
- In-reply-to: <060523081402.ZM15072@xxxxxxxxxxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <20060522205404.GA24028@xxxxxxxxxxxxxxxxxx> <060523081402.ZM15072@xxxxxxxxxxxxxxxxxxxxxx>
Bart Schaefer wrote:
> (And the doc could be
> clearer, but it all stems from the fact that zsh parameter expansion
> works by passing values of parameters, not references to parameters.)
[Moved to zsh-workers in order to ramble aimlessly.]
We really need passing by reference, though, not just for confusing cases
like this (I don't think I'd have guessed that you could use "hash[key]"
as an indirect reference, either), but for plenty of other uses.
One place I get into trouble all the time is passing back values, where
I'm always falling over the namespace problem:
sub() {
local foo
foo=something_i_needed_to_work_out
if [[ $1 = foo ]]; then
print "Oops, I've got my own foo." >&2
return 1
else
foo[thiskey]=some_expression_that_needs_passing_back_involving_$foo
foo[thatkey]=another_one
fi
}
fn() {
local -A foo
sub foo
do_something_with ${(kv)foo}
}
This sort of thing is the bread and butter of programming languages, yet
zsh has no good way of coping. Something hacked up with "reply" as an
associative array is the best I can think of at the moment.
What I'd *really* like to be able to do is this:
sub() {
local foo
<treat_as_opaque_ref($1)>=what_I_want_to_set
}
fn() {
local foo
sub <generate_opaque_reference_to_my(foo)>
}
In other words, there would be something to generate an opaque reference
(a hard, rather than a symbolic) link to foo as found in fn(), and then
another mechanism for using that reference somewhere else. fn and sub
would need to collaborate to use this, but if you can test for
parameters containing opaque references you can add backward compatible
code. In fact, it could be as simple as using a hash code in a form
that can't be a parameter name:
% print <generate_opaque_reference_to_my(foo)>
#4351267a
The opaque reference could be exactly that string, as long as we've got
a way of turning it back internally a struct pm which isn't necessarily
the current entry in the parameter table for whatever the parameter is
named. This could be made safe, for example this could be a pointer
with a parameter name; we would search through all parameters of that
name, and extract one with the address given by that pointer:
% foo=bar
% ref=<generate_opaque_reference_to_my(foo)>
% print $ref
#4351267a:foo
% print $<treat_as_opaque_ref($ref)>
bar
... [foo goes out of scope] ...
% print $<treat_as_opaque_ref($ref)>
zsh: reference to variable "foo" no longer in scope
This isn't *completely* safe, in that you could get a chance match with
a pointer to a later instance of foo; but that isn't catastrophic and
it's you're own fault for allowing it to go out of scope. The check at
least it ensures it won't crash the shell.
However, that requires a complete list of all currently defined
variables even if they're not currently in scope, and unfortunately in
some cases we remove them temporarily from the parameter table.
Ordinary local variables are relatively straightforward since they're on
a linked list tied to the same entry in the parameter table. If we can
resolve this problem there might be some mileage in the idea.
--
Peter Stephenson <pws@xxxxxxx> Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070
To access the latest news from CSR copy this link into a web browser: http://www.csr.com/email_sig.php
Messages sorted by:
Reverse Date,
Date,
Thread,
Author