Namespace Cardtype for Mounting Wagns
I want to represent information from another resource or Deck in a Wagn
Create a cardtype "Namepace" with a syntax to reference a remote Wagn or a card in the remote wagn.
The semantics is that you would "mount" the remote namespace or subtree based on a specific card would now be available locally as <Namespace Cardname>+<name in other space>
Other modules could be written to make other remote resource (e.g. WikiMedia) available as "cards" and mount them as namespaces.
I'm thinking about taking a stab at this, getting the minimum working.
In terms of representation, I think a Card gets one field, another card id called deck_id. When it is null, that is the root Deck, and it would have no Deck card. We'd have to work out some special handling for the root deck if it does have a Deck card, maybe a codename of :root would make it special if needed. We don't want to have to change the data in a deck if its mount point is changed (Deck card renamed), so presumably the names and keys in the card table would be 'deck relative'. Card ids will still be unique within a given database, so a card(_id) will imply a deck_id.
The next thing I want to think about is what methods we will want, and how existing ones are modified. I assume that .name and .cardname will be the full name with any deck names preprended, but what will we call the other parts? Seems like .deckname would reference Card[deck_id].name, but it could be the deck-relative name, then this function would be a little different. It seems like .deckcard should refer to the Card[deck_id], so I think the former is better, but then what is the deck-relative name called? Maybe .localname, .localcardname (and .localcard, but that's just the card so not needed). Initially, all decks will be local, that is contained in the same card db, but we will want to support remote decks at some point.
I note in looking at code that we don't cache anything about the name, so .cardname, .simple? and such all have to convert the string name to a cardname. I suspect that we are wasting a lot of time in this low level method. With these more complex name computations, I think it will be even more important to cache some of these values when they are computed and clear them when names are changed.
I'm thinking it would work well to put a lot of this handling in the name gem. I was going to add a second class, CompoundSmartname that is an array of a name class (Smartname by default, but probably Card::LocalName < Smartname) and Card::Name will now inherit from CompoundSmartname which should have the same API plus a few things like rootspace? and namespaced which returns the array of Smartnames representing the mount points and local names (e.g. N and N+Local+NS are both Deck cards, so N+Local+NS+A has the namespaced representation of ['N'.to_localname, 'Local+NS'.to_localname, 'A'.to_localname]).
Which brings up more questions about API, is N+Local+NS+A simple? because it is simple? within it's namespace? How about left, right, trunk and tag? We need to figure out what semantics work the best and don't disturb things. I'm thinking .to_name would return a CompoundSmartname after this change, and we would not see the Smartname derived class much.
Maybe I should be thinking about the language requirement as I'm working on this. The different kind of translation could be active on different parts of the name/namespace, correct? Also, to what extent can we use Decks and namespaces to help out with the Multi-lingual implementation?
I can't really dig into the technical aspects of the above now, but in terms of timing, I'd like to hear your strategic thinking going on before I commit a lot of my time to helping with this. I'm a little nervous to start tackling *another* major overhaul now, especially one that we hadn't really expected to integrate until after Decko 1.0, unless I really know it makes sense for the project.
My dev time is scarce and I'm already a bottleneck, so I'm a little nervous to start tackling *another* major overhaul now, especially one that we hadn't really expected to integrate until after Decko 1.0. There's going to be a lot of cleanup needed on the decko-rails stuff, and if that's left to me we may have to leave a bunch of that unmerged, because I can't really assume lead on that.
If you're really excited about this, of course, you're always welcomed to play, and I'll do my best to support you, but it will help things get merged in more quickly if there's a real plan about when and why we build which parts of the rather extensive set of solutions outlined in the DeckoSystems blueprint (formerly WagNet) and how we bring all the old existing wagns along. It would be great if everything here were in stride with that blueprint (including vocabulary btw. Here we use "mount". There we use "hitch". Perhaps the better term given our coming rebranding would be "stack"?). In some cases this will mean updating the blueprint, of course.
From a technical perspective, the place to start is probably by writing tests so we can agree on API. I know you don't like writing up API specs in text, but at least with tests you'd be writing code of a sort, and it would be a great way to organized development.
Re multilingual, I don't think that's a different kind of namespace. In fact I think the word "NameSpace" may be causing a lot of confusion here, and it may be a poor name for this Cardtype. The original proposal was for the cardtype to be called "Deck" (see DeckoSystems+names). Of course, that, too, could get confusing since we're using "Deck" to mean the app. But it also gives more meaning to the brandname (the root Deck is Deck Zero, or Deck-0).
Both Decks and Languages are namespaces. The difference is that the primary use case for Multilingual is "one concept two names", the primary focus for Deck handling is "one name two concepts". I realize that cognates mean that different languages technically have the latter pattern, too, but I hope you get the point. A new deck is for creating a new set of names for a new conceptual space. A language creates a new set of names (and values) for one space.
One other note: it's not strictly true that there is no caching involved in names now. There is a lot of (process-specific) caching on the oddly named @@name2nameobject class variable of smartname. It's basically a simple hash that does lookups of cardname objects based on the string. It's nice and simple right now, because we don't have to handle any cache clearing; nothing cached there ever gets altered.
As for your question re #simple? and such, I think a bunch of that is spelled out in (or implied by) the contextual names portion of DeckoSystems+names. (Yes, it would be simple).
Speaking of simple, please remember that compound names already has a meaning in Wagn, so you will need different terminology if you want to use it to specify a name with a deck.
I think we are fairly close together on all of this. I understand your concerns for the short term releases, which is why I was thinking in terms of trying to get in some of the necessary core support in first. I think the cardtype card will be Deck, codename deck, and we will likely have other kinds of decks in the long run. First use case is just multiple Decks in one card database with each deck being a complete namespace with semantics just like the root namespace, with the addition of the Deck cards as 'stack points' or 'attach points'
So, the first step is extending the name logic so it knows how to compose and decompose references to stacked cards. At the same time we want to add the Deck type and the deck_id to the model.
On multi-lingual stuff, I agree that we are not wanting a namespace for each language, but I'm saying we should use the terminology of namespaces and build some parts of language support into the name logic. In other words, namespacing is a concept for parsing (decomposing) names, and we will use it for finding the stack points of a name, but we can also use it for finding different translation modes for different parts of the names. We want to add minimally to the name gem. It doesn't know what you want namespaces for, just that you want to organize the global namespace (all possible smartnames) into subspaces. And we have at least two kinds of namespace, stand-alone ones where DeckPoint+A is simple? and maybe another kind that is just for contextual interpretation of name parts which is more what we need for languages.
And, yes, your are right about the caching. Object.to_name is really fast except the first time it sees a name, so it doesn't hurt much to do it over and over.
If the namespace configuration changes at runtime, we'll need to clear some of those caches. Mostly we'll want them to load at startup/load time. Adding or removing Deck cards, or changing the namespace configuration for translations won't happen that much.
I've used the term and method name 'namespaced' to get at the raw parts of the names. The terminology issue we need to jump on is about what we call the different name contexts and relative names. Deck-based, root-deck based, site based ... The current code that I'm playing with stores the parts as strings because only the first one actually names a card in the absolute (root-deck based) sense. We'll want methods to get a list of the stacked namespace cardnames and the full name (final element).
+discussed in support tickets
+relevant user stories