Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: named references



On Jun 24, 12:34pm, Oliver Kiddle wrote:
} 
} I've attached the text file where I've been jotting down any issues I've
} thought of. There are a number of unusual issues (like the one with for
} loops) so it is quite possible I've missed something.
} 
} I've also attached a patch of what I've done so far

Having had a quick look at your patch, two things come to mind.

First, I wish it wasn't necessary to waste an entire `struct param' on a
nameref.  It's got a bunch of extra fields that a nameref can't possibly
need.  I'd say you should create a new type of hash node, except that the
implementation of `local' depends so much on the guts of `struct param'.

Second, I think you're dealing with dereferencing in too many separate
places.  It's almost always the case that dereference is wanted -- the
only exception seems to be `unset -n'.  This suggests that dereference
should be a hashtable-level operation rather than parameter-name-level.

So I'd suggest adding to the union:

    /* the value of this parameter */
    union {
	void *data;		/* used by special parameter functions    */
	char **arr;		/* value if declared array   (PM_ARRAY)   */
	char *str;		/* value if declared string  (PM_SCALAR)  */
	zlong val;		/* value if declared integer (PM_INTEGER) */
	double dval;		/* value if declared float
				                    (PM_EFLOAT|PM_FFLOAT) */
        HashTable hash;		/* value if declared assoc   (PM_HASHED)  */
	HashNode ref;		/* value if declared nameref (PM_NAMEREF) */
    } u;

Then specialize getparamnode() and related functions to deref through the
u.ref field, and leave most of the rest of the parameter code alone.  Use
another SCANPM_* flag, which can be passed through fetchvalue(), to tell
when NOT to do this extra dereference.

The potential complication of the above is with `unset' of the node that
is pointed-to.  It'll have to be more careful about freeing the memory;
It'll have to set the PM_UNSET flag instead, and re-use the node if it
becomes set again.  The other option is to continue using u.str as your
patch does, and make a recursive call to getnode() or whatever, but that
complicates other operations (like your overloading of `ct' to plus an
extra loop to determine what `level' to look up in the referenced param).

} I have not implemented ksh93's ${!ref}
} which expands to whatever ref is a reference to. This syntax is a csh
} style history reference in zsh, so I feared that any attempt by me to
} implement it would break something else.

I don't think that's an issue.  Just implement it in the most direct
way, without paying any attention to history, and it'll "just work" in
ksh emulation mode when nobanghist is in effect.  Then also provide a
corresponding expansion flag for regular zsh use.

} with a parameter expansion flag (possibly two to allow a single
} dereference in addition to ksh's full dereference?)?

I don't think that's necessary, but it raises the question of what really
happens when a reference-to-a-reference is made.  That is:

	typeset v1 v2
	typeset -n r1=v1
	typeset -n r2=r1
	typeset -n r1=v2

At this point, is r2 still a reference to v1, or has it become a reference
to v2?  That is, is r1 dereferenced at the time of assignment to r2, or
not until time of dereference of r2?  This ...

} cycles and self-references blocked
}   $ typeset -n ref=val
}   $ typeset -n val=ref
}   ksh: typeset: val: invalid self reference

... tends to indicate that a dereference is performed at the time of the
assignment, if only to discover the loop.

I'm also a bit confused by this:

} also, the element of an array, assoc can not be a reference, just as it
} can't be a float etc:
}   $ typeset -n ref[1]=val
}   ksh: typeset: ref: reference variable cannot be an array

Because later you say:

} in ksh, typeset -n ref[one]=val is allowed with [one] ignored

Which is it?

} references can't be exported
} local applies to the reference not the variable

What exactly does "local applies to the reference" mean?  I presume it
means it hides the name of the nameref, turning it into a local name
that may not even be a nameref any more.

} in ksh though:
}   $ typeset -n -r ref=val
}   ksh: typeset: ref: is read only
} might be good if this would define ref as a readonly reference

I don't understand what the ksh error message means has happened.  I do
understand what you mean by a read-only reference:  It would mean that
an assignment `val=newval' would succeed, but `ref=newval' would not.
  
} typeset +n ref converts ref to a scalar

A scalar having what value?  The name of the previously referenced param?

} if ksh is given an nameref as the index to a for loop it assigns the
} values as for the reference, not the value. It could be very useful
} but isn't what what you'd first expect. Is there a good alternative to
} avoid this:
}   $ typeset -n ref=dummy
}   $ for ref in var1 var2 ...

So what you mean is that, in ksh, the two lines above are the same as

    for name in var1 var2; do typeset -n ref=$name; ...

Hence at the end of the loop `typeset ref' will say `nameref ref=var2'?
(Or does `typeset ref' not work that way?  See below.)

} reference records the local level [...]
} because of the above, it needs to handle the situation where
} unset ref is done in the function above and also where ref is
} then also reassigned a value.

Using an actual u.ref pointer to the referenced node would deal with all
of this in a very straightforward manner, I think.
 
} ksh is not clever enough to allow typeset -n ref=ref in a function though

What is the actual complaint?
 
} Extra issues in zsh:
} 
} local should be implied for typeset -n without +l.

You mean without -g ?  +l is `not lowercase'.  I suppose ksh has used -l
for `local'?  (See previous mail I've sent about whether ksh emulation
mode should change the meanings of some options to typeset.)

} what should ${(t)ref} return - the same as what it refers to with -nameref-
} inserted?

It should correspond to `typeset -n ref=val; typeset ref'.
 
} should we use namerefs for prompt, rprompt, PROMPT-PROMPT4?

Possibly.  Definitely we should for ZLS_COLO(|U)RS, colo(|u)rs, etc.

} how messy will references to specials be?

I think they won't be messy with my suggested implementation, but I admit
I haven't tried to work out all the details.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   



Messages sorted by: Reverse Date, Date, Thread, Author