List attribute options

I found this old thread while looking up how to populate the suggested values of a list attribute. I want to add the example I’m working on, since it isn’t working for me yet (and I’m not sure what I’m missing).

I have:

  • a note called /Roles that contains several notes, each being a job role that someone might be interested in taking on; the $Name of each is the job title
  • a prototype called Learner, representing a person who’s learning technical subjects
  • a list-valued field in Learner called RoleInterests, representing roles a particular person’s interested in taking on

I want the suggested values for RoleInterests to be populated with the names of the roles, i.e., the $Name of each child of /Roles.

From what I read here, I can get (for example) the $Text of Roles to contain the list of its child titles, no problem. Per this page, it seems I should be able to run an action like

attribute("RoleInterests")["suggested"] = "foo;bar;baz"

on Learner to set the suggested values, and that to draw these values from Roles I could write

attribute("RoleInterests")["suggested"] = collect(children($Roles), $Name).sort

in a Stamp applied to Learner. However, this doesn’t seem to have an effect—and for all I know, perhaps this isn’t the ideal way to be doing what I’m doing. So, could y’all point me in the right direction?

I’m using 9.1.0 (b542).

Thanks!

Well, it should work, but I can confirm it doesn’t testing here in v9.1.0. not sure what’s amiss but I have reported it.

Assuming it returns to service, a note on your planned code:

attribute("RoleInterests")["suggested"] = collect(children($Roles), $Name).sort

You can’t use a path or name offset on a designator like children, though you can nest designators as in parent(original). Also I think you meant (looking at you post) to use Roles rather than $Roles as the latter would read a value form an attribute ‘Roles’ in the currently selected note. So, in this case you need to use find() with query, so like:

collect(find($Container(original)=="Roles"), $Name)

Of course until attribute() is fixed, it is all moot.

Also, if RoleInterests is a set, you don’t need the .sort as Sets now auto-sort alphabetically. Indeed, value pop-up lists in Displayed Attributes and Get Info auto-sort too.

Alright!

So if I understand correctly, this is what I want to put in a Stamp (or Rule or Edict) applied to Learner:

attribute("RoleInterests")["suggested"] = collect(find($Container(original) == "/Roles"), $Name)

In the meantime, I already wound up typing the roles into the RoleInterests field, so I can’t tell if the stamp had an effect or if the names I’m seeing are there because I already typed them. But I can make progress, so I’m happy for now.

Thanks for the reply!

Yes - but noting it won’t work until the issue with setting values via attribute() is fixed.

I note ‘Roles’ is at root level so you may need to use either /Roles unquoted or "Roles" (quoted, without the opening /, i.e. either unquoted $Path or quoted $Name. This quirk pertains to root-level notes only and I’m not entirely sure as to the underlying issue.

@mwra—Funny thing. I’ve just spent the last couple of hours trying to figure out how to set “default” and “suggested” for attributes. I was getting ready to report this problem, and see you’ve already documented and reported the problem.

Since this subject has come up, it would be very useful to be able to set the “description” for an attribute as well.

I will further note that when using the “attribute” operator to retrieve the settings for an attribute, these forms work:

$MyList=attribute($MyString)["default"];
$MyList=attribute($MyString)[default];
$MyList=attribute($MyString)["suggested"];
$MyList=attribute($MyString)[suggested];
$MyList=attribute($MyString)["type"];

However, this does not work:

$MyList=attribute($MyString)[type];

This is presumably because there is an operator called “type,” which retrieves the type of an attribute.

My notes on attribute() specify keys should be quoted. I would have taken that lead from official release notes. If the docs say quote, then quote and treat is as a rule not an option.

This is part of the wider ‘when to quote a string value’ dilemma. My general, rule of thumb is to quote all literal string values, except:

  • named designators (this apparently helps Tinderbox look for a designator match before testing $Name or $Path)
  • paths (i.e. a $Path value, but not for $Name as per previous bullet)

Part of the underlying issue is Action codes early years with minimal syntax. So then:

Color = blue

vs. now

$Color = "blue";

In your non-quoted key example, I assume Tinderbox looked for a designator named ‘type’ (even though they aren’t used in this context) and finding none failed silently. Spelunking why code fails is hard due to the loose enforcement of syntax norms surrounding quoting.

In part the increasing complexity has driven the need for more syntax. At the same time support for legacy syntax (and not forcing existing users to update their code) allows ‘old’ methods to survive. A negative aspect of this is occasional users a don’t feel the need to learn the newer syntax and many older files/samples use out-of-date syntax, further adding to the confusion.

In theory we might posit a ‘strict’ switch forcing application of quoting rules. But, first those rules would need formalising. For my 2¢, I think we’re easily past the point where the benefits of that would outweighs the demerits. Working on some v5-era files, I was surprised quite how much work was needed to get them ready for v9 use. Much was tidying (pruning extra windows, updating attribute defaults, etc.)

†. Before the new UI of v6, Tinderbox supported a lot of discrete window (text and views). When such a file is opening in v6+ every window in the old doc opens as a full document window and as doc windows share a same focus (unhelpfully IMO) you end up with lots of seeming duplicate windows. As screen sizes were smaller and layout mote compact, the window(s) need making bigger as may be the need with some icons on maps, etc. Regardless of above, some query terms need fixing, e.g. old Text("#+") becomes current $Text.contains("#+").

1 Like

@mwra—Thanks for the detailed clarification and explanation of the evolutionary paths that got us to where we are today. This really does help clear up some of the sources of confusion.

I agree that your aTbRef discussion of the attribute operator only shows the quoted use for keys. My apologies for confusing this issue for others.

However, the description of the document operator does state and illustrate that “Quotes around the key are optional.” Since the attribute and document operators are often used together in code, and appeared to have similar usage conventions, I experimented with the unquoted keys in the attribute operator in my efforts to try to use the attribute operator to update the “default” and “suggested” configurations of a user attribute from within Action code.

I absolutely agree that the variant that always works as expected should be what gets documented. So, should the same approach be taken with the document operator? At the very least, my take-away is that keys entered as literals for both attribute and document operators should, by convention, always be quoted. I’d prefer a consistent convention to avoid having to apply a convoluted set of mental conditionals to determine what does, or does not work.

My purpose in providing this response is to alert others working with these operators, so that they can avoid the question marks that I pondered and explored via experiments.

I’ll fix that (busy ATM but probably tomorrow)

Indeed, I’m minded to stop documenting (and remove existing references to) options mainly there for legacy use or for expert coders (who have the smarts to figure out silent fails). I think it more useful to community at large to document what works rather than what might work. The only valid optional context as export/action code optional inputs [sic]

†. For the same reasons I’m minded to normalise terminology in a vocabulary note (or more likely a number of notes). I think it makes sense to write for ordinary folk who need help; experienced folk who at worse may be upset their preferred terminology is not the one of choice can still use the info.

1 Like