def [a_key]
return nil unless @attr.keys.include?(a_key)
return @attr[a_key]
end
def
return @attr[a_key]
end
but yes, that’s a good option. By default hashes return nil when you
dereference a key that doesn’t exist, so unless you’ve changed that
(by creating it with Hash.new(…) or similar) then you can leave that
first line out.
but yes, that’s a good option. By default hashes return nil when you
dereference a key that doesn’t exist, so unless you’ve changed that
(by creating it with Hash.new(…) or similar) then you can leave that
first line out.
Ben
You can also remove the “return” and leave it like this:
But it starts to become really interesting if methods can disappear.
Of course we could just use method_missing without defining a getter,
but having an observer on @atts that would add remove methods on the
receiver would be quite an elegant approach.
Unfamiliar with built in observers I have made a sketch of how I would
like to implement such a functionality here http://pastie.org/961738
But the question remains, whether this is a good idea. Think about it:
either you do not know keys beforehand. Then you can only use generic
algorithms (i.e. query all keys and print their values). Or you do know
keys beforehand and then you want to explicitly access individual keys
(e.g. obj.name).
If you know the names you can use Struct, e.g.
First, thanks a lot for your answer !
Thats’s my case, i know in advance all of the keywords.
In fact i get a String as input, something like :
“name: the_name_value, modification date: the date & time in default
lang, …”
and i populate a hash :
h[:name] = the_name_value
h[:modification_date] = DateTime of(“the date & time in default lang”)
et c…
But the question remains, whether this is a good idea. Think about it:
either you do not know keys beforehand. Then you can only use generic
algorithms (i.e. query all keys and print their values). Or you do know
keys beforehand and then you want to explicitly access individual keys
(e.g. obj.name).
If you know the names you can use Struct, e.g.
irb(main):011:0> St = Struct.new :foo, :bar
=> St
irb(main):012:0> s = St[*S.members.map{|m| ha[m]}]
=> #
irb(main):013:0> s.foo
=> 2
irb(main):014:0> s.bar
=> 3
irb(main):015:0>
i had a first look and i wonder how to use it in order to get a new
class “HFSFile” which can be used such a way, using OpenStruct :
hfsf = HFSFile.new(a_path)
p hfsf.path
p hfsf.modification_date
…
because i do :
class HFSFile
def initialize(a_path) @attr = {} @attr[:path] = a_path @attr[:modification_date] = …
… @data = OpenStruct.new(@attr)
end
def attributes
return @attr
end
def data
return @data
end
end
what is ennoying me in that case is in that i do have to use :
hfsf = HFSFile.new(a_path)
p hfsf.data.path
p hfsf.data.modification_date
------^^^^^^-----------------
…
where i would prefer having self being an OpenStruct (extension ?) but i
think i can’t do :
self = OpenStruct.new(@attr)
…
end
p hfsf.data.path
p hfsf.data.modification_date
------^^^^^^-----------------
…
where i would prefer having self being an OpenStruct (extension ?) but i
think i can’t do :
self = OpenStruct.new(@attr)
???
There is no need for delegation here: you only need one instance and the
way through Hash or OpenStruct seems a detour here - at least if the set
of fields is fixed. Then you can do
HFSFile = Struct.new :name, :modification_date do
def self.parse(s)
o = new
s.scan /\s*([\w\s]+):\s*([^,]+),?/ do
field = normalize($1)
val = $2.strip
o[field] = val
end
o
end
def self.normalize(k)
k.strip.gsub /\s+/, ‘_’
end
end
You’ll get a NameError if you parse fields from the String that are not
present in the struct. If you need to cope with additional fields you
need to either ignore them or store them in an additional Hash member.
You can use HFSFile.members (or just members in method parse()) to test
for field presence.
You’ll get a NameError if you parse fields from the String that are not
present in the struct. If you need to cope with additional fields you
need to either ignore them or store them in an additional Hash member.
You can use HFSFile.members (or just members in method parse()) to test
for field presence.
OK, i see it’s really fine of u helping that way !
in fact i do have a number of keys (18).
and a new prob arroses : i’d like to add new keys depending on the file
type (the input is a file path).
if the file path refers to an alias file (Mac OS X) one of the keys ( a
boolean) give me that allready but, in that case, i’d like to add a new
key :alias_broken (the original item of the alias has been deleted) i
suppose i could do that easily :
self.alias_broken = true|false
and in ruby generally the methods returning a boolean are named with an
ending “?”, a good habit.
obiously, i know when this is a boolean because the string value is
“true”|“false”.