[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Keyword precedence



About a month ago, as part of the "Top 10 IDL Requests" thread (Aaah, those
were the days!) Jeff Guerber wrote:

>>    12) Something like "_extra=", but which does _not_ override keywords
>> explicitly specified on the call line; "_default=", perhaps.

And I replied:

> I think the way you want _extra to work is the way it *should* work
> and I don't think it would break too much code if it *did* work that
> way. So I don't support "_default".

This was a very careless reply. In my defence I should note that I *did* say
in the next paragraph that I was somewhat confused about this matter. I have
had occasion to revisit keyword precedence since and my confusion has
cleared somewhat. I have also discovered an anomaly that has been in IDL
since version 5.2 and earlier and may have been part of the reason for my
confusion. (But at my age I find that, while I know I am confused about a
lot of things, I can never quite remember why.)

The documented behaviour for IDL--the behaviour to which Jeff was
referring--is specified in the following quote from "Building IDL
Applications"

    Note that keywords passed into a routine via _EXTRA override
    previous settings of that keyword. For example, the call:

        PLOT, a, b, COLOR=color, _EXTRA={COLOR: 12}

    specifies a color index of 12 to PLOT.

Contrary to what I wrote a month ago, I think this is usually the desired
behaviour, because it makes it easy to write wrapper routines. For example,
taking the PLOT example, one can imagine a MY_PLOT routine, a wrapper for
PLOT, that specifies its own default for colour:

pro my_plot, a, b, _EXTRA=extra
    plot, a, b, COLOR=127, _EXTRA=extra
end

MY_PLOT will plot data in color 127 unless the caller overrides it by
specifying a COLOR keyword. If we can't rely on the documented behaviour
then we have to make MY_PLOT more complicated, thus:

pro my_plot, a, b, COLOR=color, _EXTRA=extra
    if n_elements(color) eq 0 then color = 127
    plot, a, b, COLOR=color, _EXTRA=extra
end

Anyone who has looked at the code on my WWW page will see many examples of
the latter style. I would prefer to use the former!

I mentioned an anomaly. This is illustrated by set of routines in the
following .PRO file:

http://katipo.niwa.cri.nz/~hadfield/gust/software/idl/  ->
mgh_example_keywords.pro

A copy of the file is also attached.

The routine MGH_EXAMPLE_KEYWORDS passes
a COLOR value to a routine that prints it. The colour-printing
routine is called directly, then through a wrapper that uses inheritance by
value, then through a different wrapper that uses inheritance by reference.
The output on my machine shows an anomaly: the value of COLOR received at
the end of the chain differs depending on the routines in the chain.
Reference inheritance appears to be broken.

% MGH_EXAMPLE_KEYWORDS: Calling color-print routine directly
% MGH_EXAMPLE_KEYWORDS_PRINT_COLOR: COLOR is 12
% MGH_EXAMPLE_KEYWORDS: Calling color-print routine via value wrapper
% MGH_EXAMPLE_KEYWORDS_VALUE_WRAPPER: Passing along EXTRA keywords in
structure:{      12}
% MGH_EXAMPLE_KEYWORDS_PRINT_COLOR: COLOR is 12
% MGH_EXAMPLE_KEYWORDS: Calling color-print routine via reference wrapper
% MGH_EXAMPLE_KEYWORDS_REFERENCE_WRAPPER: Passing along EXTRA keywords by
reference
% MGH_EXAMPLE_KEYWORDS_PRINT_COLOR: COLOR is 0

This is important, especially in object-oriented programming, when a
superclass's Init method is extended in a series of subclasses, each of
which might want to establish its own defaults for an object's properties.
It seems that if reference inheritance is used in the chain one can't rely
on the documented precedence.

I have raised this with IDL support and I hope they will recognise it as a
bug and fix it. But since this behaviour has been around for several
versions of IDL I thought I should publicise it on the group. For myself, I
would like to take advantage of the simpler coding style allowed by the
documented precedence. The solution, I think, is to use value-inheritance in
all cases where it is permissible, i.e. where information is only being
passed into a routine, not out. In OO programming this restriction is not
usually a problem because the conventional methods for manipulating an
object's properties are cleanly divided into those where information goes in
(Init & SetProperty) and those where it comes out (GetProperty).

Returning to Jeff's proposal, does anyone else see a need for a _DEFAULT
formal keyword parameter. I don't, but that may be because I am still
confused!

---
Mark Hadfield
m.hadfield@niwa.cri.nz  http://katipo.niwa.cri.nz/~hadfield/
National Institute for Water and Atmospheric Research
PO Box 14-901, Wellington, New Zealand







begin 666 mgh_example_keywords.pro
M.R!4:&ES(')O=71I;F4@=&5S=',@=&AE(&9O;&QO=VEN9R!A<W-E<G1I;VX@
M*&9R;VT@(D)U:6QD:6YG#0H[($E$3"!!<'!L:6-A=&EO;G,B*3H-"CL-"CL@
M("!.;W1E('1H870@:V5Y=V]R9',@<&%S<V5D(&EN=&\@82!R;W5T:6YE('9I
M82!?15A44D$@;W9E<G)I9&4-"CL@("!P<F5V:6]U<R!S971T:6YG<R!O9B!T
M:&%T(&ME>7=O<F0N($9O<B!E>&%M<&QE+"!T:&4@8V%L;#H-"CL-"CL@(" @
M(" @4$Q/5"P@82P@8BP@0T],3U(@/2!C;VQO<BP@7T585%)!(#T@>T-/3$]2
M.B Q,GT-"CL-"CL@("!S<&5C:69I97,@82!C;VQO<B!I;F1E>"!O9B Q,B!T
M;R!03$]4+@T*.PT*.R!);B!)1$P@-2XQ(&%N9"!E87)L:65R('1H:7,@9&ED
M(&YO="!H;VQD('1R=64@:68@:V5Y=V]R9',-"CL@=V5R92!P87-S960@9&]W
M;B!A(&-H86EN(&]F(')O=71I;F5S+B!)(')A:7-E9"!W:71H(%)320T*.R!4
M96-H(%-U<'!O<G0@86YD(&ET('=A<R!A<'!A<F5N=&QY(&9I>&5D(&EN($E$
M3" U+C(N(%1E<W1I;F<-"CL@=&AI<R!W:71H($E$3" U+C,@22!F:6YD('1H
M870@=&AE('-P96-I9FEE9"!P<F5C961E;F-E(&AO;&1S(&9O<@T*.R!A('=R
M87!P97(@<F]U=&EN92!T:&%T('5S97,@=F%L=64@:6YH97)I=&%N8V4@8G5T
M(&YO= T*.R!F;W(@=&AE(&]N92!T:&%T('5S97,@<F5F97)E;F-E(&EN:&5R
M:71A;F-E+@T*#0IP<F\@;6=H7V5X86UP;&5?:V5Y=V]R9'-?<')I;G1?8V]L
M;W(L($-/3$]2/6-O;&]R+"!?15A44D$]97AT<F$-"@T*(" @(&UE<W-A9V4L
M("]I;F9O<FTL("=#3TQ/4B!I<R G("L@<W1R=')I;2AC;VQO<BPR*0T*#0IE
M;F0-"@T*<')O(&UG:%]E>&%M<&QE7VME>7=O<F1S7W9A;'5E7W=R87!P97(L
M(%]%6%1203UE>'1R80T*#0H@(" @;65S<V%G92P@+VEN9F]R;2P@)U!A<W-I
M;F<@86QO;F<@15A44D$@:V5Y=V]R9',@:6X@<W1R=6-T=7)E.B<@*R!S=')I
M;F<H97AT<F$L("]04DE.5"D-"B @("!M9VA?97AA;7!L95]K97EW;W)D<U]P
M<FEN=%]C;VQO<BP@7T585%)!/65X=')A#0H-"F5N9 T*#0IP<F\@;6=H7V5X
M86UP;&5?:V5Y=V]R9'-?<F5F97)E;F-E7W=R87!P97(L(%]2149?15A44D$]
M97AT<F$-"@T*(" @(&UE<W-A9V4L("]I;F9O<FTL("=087-S:6YG(&%L;VYG
M($585%)!(&ME>7=O<F1S(&)Y(')E9F5R96YC92<-"B @("!M9VA?97AA;7!L
M95]K97EW;W)D<U]P<FEN=%]C;VQO<BP@7T585%)!/65X=')A#0H-"F5N9 T*
M#0IP<F\@;6=H7V5X86UP;&5?:V5Y=V]R9',-"@T*(" @(&UE<W-A9V4L("])
M3D9/4DTL("=#86QL:6YG(&-O;&]R+7!R:6YT(')O=71I;F4@9&ER96-T;'DG
M#0H@(" @;6=H7V5X86UP;&5?:V5Y=V]R9'-?<')I;G1?8V]L;W(L($-/3$]2
M/3 L(%]%6%1203U[0T],3U(Z,3)]#0H-"B @("!M97-S86=E+" O24Y&3U)-
M+" G0V%L;&EN9R!C;VQO<BUP<FEN="!R;W5T:6YE('9I82!V86QU92!W<F%P
M<&5R)PT*(" @(&UG:%]E>&%M<&QE7VME>7=O<F1S7W9A;'5E7W=R87!P97(L
M($-/3$]2/3 L(%]%6%1203U[0T],3U(Z,3)]#0H-"B @("!M97-S86=E+" O
M24Y&3U)-+" G0V%L;&EN9R!C;VQO<BUP<FEN="!R;W5T:6YE('9I82!R969E
M<F5N8V4@=W)A<'!E<B<-"B @("!M9VA?97AA;7!L95]K97EW;W)D<U]R969E
M<F5N8V5?=W)A<'!E<BP@0T],3U(],"P@7T585%)!/7M#3TQ/4CHQ,GT-"@T*
'96YD#0H-"@``
`
end