Mailinglist Archive: yast-devel (144 mails)

< Previous Next >
Re: [yast-devel] Questions about some YCP Equivalents in ruby
Dne 13.8.2013 14:15, Thomas Fehr napsal(a):
On Tue, Aug 13, Lukas Ocilka wrote:
part["format"] = false
part.fetch("format", true) --> returns false
part["format"] || true --> returns true

I see, thanks for mentioning this.
So the above construct works for every type except bool.
Neverthless I rewrote it using method fetch (that so far I did not know)

There are more possibilities how to handle missing keys.

Hash.fetch, as mentioned above, has a disadvantage that you need to repeat
the same default in every fetch() call which is error prone.


The are other possibilities for setting the default:

- Hash.new(<default>) - the hash returns the default when the key is missing,
sets the default when creating the hash

- my_hash.default = <default> - sets/updates the default, similar to the above
but can be used later (for already existing hash)

The disadvantage is that there is just a single default value so it cannot
be used for

part["fsid"]:0
part["type"]:`none

replacement where you need different default values/types.


However there is another possibility, the new() method takes a block as well:
(see http://www.ruby-doc.org/core-2.0/Hash.html#method-c-new)

a = Hash.new do |h, k|
case k
when "fsid"
0
when "type"
:none
else
nil
end
end

Then it works like this:

# try the defaults
a["fsid"] => 0
a["type"] => :none
# fallback for unknown key
a["foo"] => nil

# but beware, these keys actually do not exist in the hash and are not returned
# by keys() method as they are not stored there!
a.keys => []

# of course, setting something overrides the defaults
a["fsid"] = 42
a["type"] = :foo
# read the real stored values
a["fsid"] => 42
a["type"] => :foo

# after storing the values above the keys are visible
a.keys => ["fsid", "type"]


The advantage of this solution is that the defaults are set at one place and
you do
not have to repeat them all over again. You just need to be careful when reading
stored keys and when iterating over the hash as the defaults are not stored and
thus
not returned. (But that is the same as in YCP, so it should be not a problem.)


You can even raise an exception when accessing an unknown key, simply change the
default in the "else" branch of the case:

...
else
raise "unknown key #{k}"
end


Then e.g. a["foo"] raises "RuntimeError: unknown key foo" exception, this
way you could catch some wrong usages of the hash (if the set of keys is fixed
and known in advance).


Anyway, in the long term we should replace the "part" hash by a native Ruby
object
with appropriate attributes, that would solve all the problems...

--

Ladislav Slez√°k
Appliance department / YaST Developer
Lihovarsk√° 1060/12
190 00 Prague 9 / Czech Republic
tel: +420 284 028 960
lslezak@xxxxxxxx
SUSE
--
To unsubscribe, e-mail: yast-devel+unsubscribe@xxxxxxxxxxxx
To contact the owner, e-mail: yast-devel+owner@xxxxxxxxxxxx

< Previous Next >
Follow Ups