Quoting [Ceriel Jacobs] (Nov 04 2009):
Andre Merzky wrote:
Quoting [Mathijs den Burger] (Nov 04 2009):
Hi all, ... 2. Removing SAGA attributes is permanent (AFAIK when talking to Ceriel), while a deleted dict item can be re-added latter
Not sure I undestand. the following should be valid:
if ( ! advert.attribute_exists ("foo") ) { advert.set_attribute ("foo", "bar"); }
assert (advert.attribute_exists ("foo"), true);
advert.remove_attribute ("foo");
assert (advert.attribute_exists ("foo"), false);
advert.set_attribute ("foo", "bar");
assert (advert.attribute_exists ("foo"), true);
Actually, I have an issue with this: I don't think this is valid.
Here is why, and it all depends on what the Saga specs mean by "exists". The notes at set_attribute say, a.o.: "the attribute is created, if it does not exist" and also "only some SAGA objects allow to create new attributes - others allow only access to predefined attributes. If a non-existing attribute is queried on such objects, a 'DoesNotExist' exception is raised". I take this to mean that ALL attributes mentioned in the SAGA specs DO exist, even if they don't have a value. Now, remove_attribute has as PostCond: "the attribute is not available anymore." I assume this means: "the attribute does not exist anymore", what else would it mean?
Absolutely correct so far, IMHO!
So, attribute_exists() returns false on a removed attribute, but then a call to set_attribute() gives a "DoesNotExist".
Here however you have two cases, as you actually quoted earlier:
"only some SAGA objects allow to create new attributes - others allow only access to predefined attributes. If a non-existing attribute is queried on such objects, a 'DoesNotExist' exception is raised".
FWIW, we call the objects which allow to create new attributes 'extensible'. So, it is void saga::object::set_attribute (key, val) throws { switch ( extensible_ ) { case true: // always set attribs_[key] = val; case false: // object is not extensible: only set attribute if it is one // of the allowed attributes if ( allowed_[key].count != 0 ) { // is a predefined attrib, can set attribs_[key] = val } else { // not extensible, not predefined: error throw saga::excdeption::does_not_exist ("object is not extensible, " "and " + key + " is not allowed"); } } } Does that make sense to you?
From Mathijs, I understand that the C++ implementation has a different take on what "exists" means. I may even like that interpretation better, but I don't think it is supported by the current Saga specs.
I am obviously very biased, working with C++ mainly. But at the moment I don't see a clash with the spec. Earlier however I discussed with Mathijs, and agree that the spec is unclear about which attributes are actually optional and which are mandatory. For example, 'Executable' on the job description is mandatory, all others on jd are optional. It is not extensible. Thus, IMHO, the following should hold: saga::job::description jd; // only lists one attrib: Executable assert (js.list_attributes ().count (), 1); // note: c++ is broken here as it shows an empty list - it only // complains when using the jd. I am fine with that one, too, but // the spec says differently, IMHO. // can set allowed attribs js.set_attribute ("PWD", "/tmp"); assert (js.list_attributes ().count (), 2); // empty string is valid value js.set_attribute ("PWD", ""); assert (js.list_attributes ().count (), 2); // removal removes key and val js.remove_attribute ("PWD", "/tmp"); assert (js.list_attributes ().count (), 1); js.set_attribute ("foo", "bar"); // throws, not allowed Basically, I think attribs should behave like a possibly pre-populated, a key-restricted hash table. So, lets see if that makes sense to you, and others, and if that actually matches the spec :-) Thanks, Andre.
Cheers, Ceriel
-- Nothing is ever easy.