zsh-workers
 help / color / mirror / code / Atom feed
* Re: values of associations pointed by P flag
       [not found] ` <060523081402.ZM15072@torch.brasslantern.com>
@ 2006-05-25 15:15   ` Peter Stephenson
  2006-05-25 23:56     ` Bart Schaefer
  0 siblings, 1 reply; 2+ messages in thread
From: Peter Stephenson @ 2006-05-25 15:15 UTC (permalink / raw)
  To: Zsh hackers list

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@csr.com>                  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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: values of associations pointed by P flag
  2006-05-25 15:15   ` values of associations pointed by P flag Peter Stephenson
@ 2006-05-25 23:56     ` Bart Schaefer
  0 siblings, 0 replies; 2+ messages in thread
From: Bart Schaefer @ 2006-05-25 23:56 UTC (permalink / raw)
  To: Zsh hackers list

On 5/25/06, Peter Stephenson <pws@csr.com> wrote:
>
> 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)>
>   }

Of course in ksh "generate_opaque_reference_to_my(foo)" is

  nameref opaque=foo

which (if I understand it correctly, which I might not) acts roughly
like "local -h opaque" does in zsh in terms of scoping, but makes the
value of $opaque equivalent to the value of $foo and similarly causes
any assignments to opaque to be assigned through to foo.

> % 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

That's an interesting suggestion for a way to impement namerefs.
Rather than really passing the reference around, which would require a
massive rewrite of the parameter code, return as the value a magic
string that gets processed "as if" with ${(P)...} at the critical
juncture.  The important bit is that such a string has to be
impossible to create by any other means, and has to encode how to
select both the paramscope and the parameter that are of interest.

> % foo=bar
> % ref=<generate_opaque_reference_to_my(foo)>
> % print $ref
> #4351267a:foo

See, this should never happen.  The parameter code should internally
recognize the magic value of $ref and replace it with (in this case)
"bar".  The trick may be in knowing at when to do the conversion.
Subscripts need to be applied to the referent, not to its value.  (We
have a bit of a complication in that plain arrays are subscriptable as
compound values even after the referent is lost, but hashes are not.)

> ... [foo goes out of scope] ...
> % print $<treat_as_opaque_ref($ref)>
> zsh: reference to variable "foo" no longer in scope

This would never happen with the scheme I describe, because the named
reference can never refer to a parameter at a "deeper" scope; that is,
foo and its opaque reference could go out of scope at the same time,
or the reference could go out of scope first, but foo could not go
first.

> 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.

If the reference can't "look down", then it only requires the current
state of the parameter table when creating one, right?  You can get to
wider scopes via existing references or through the current naming
scope, but you don't need to enumerate *all* variables.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-05-25 23:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20060522205404.GA24028@ulpmm.u-strasbg.fr>
     [not found] ` <060523081402.ZM15072@torch.brasslantern.com>
2006-05-25 15:15   ` values of associations pointed by P flag Peter Stephenson
2006-05-25 23:56     ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).