How to make "generic" YAML calls?

D

dale.quigg

Hi,

I have a Test.Yaml file like;
This:
Thing: Foo
That:
Thing: Bar

My program works with this code;
require 'yaml'
LocalTree = YAML.load_file("test.yaml")
puts LocalTree["This"]["Thing"]
puts LocalTree["That"]["Thing"]

However, I want to write a class where I pass something like
'["This"]["Thing"]'
or
'["That"]["Thing"]'
and then make a call like;
puts LocalTree@YamlLocation
but I can't figure out how to make this work.

Any hints/tips appreciated.

Thanks,
Dale
 
D

dale.quigg

However, I want to write a class where I pass something like
'["This"]["Thing"]'
or
'["That"]["Thing"]'
and then make a call like;
puts LocalTree@YamlLocation
but I can't figure out how to make this work.

Found it, sorry to bother.
yaml_vari = '["This"]["Thing"]'
puts eval("LocalTree" + yaml_vari)
 
G

Gregory Seidman

} <snip>
} > However, I want to write a class where I pass something like
} > '["This"]["Thing"]'
} > or
} > '["That"]["Thing"]'
} > and then make a call like;
} > puts LocalTree@YamlLocation
} > but I can't figure out how to make this work.
}
} Found it, sorry to bother.
} yaml_vari = '["This"]["Thing"]'
} puts eval("LocalTree" + yaml_vari)

In general, eval should be avoided. Try this:

def retrieve(*path)
path.inject(LocalTree) { |obj,key| obj[key] }
end

Call it as retrieve('This', 'Thing'), for your example.

--Greg
 
D

dale.quigg

Gregory said:
} <snip>
} > However, I want to write a class where I pass something like
} > '["This"]["Thing"]'
} > or
} > '["That"]["Thing"]'
} > and then make a call like;
} > puts LocalTree@YamlLocation
} > but I can't figure out how to make this work.
}
} Found it, sorry to bother.
} yaml_vari = '["This"]["Thing"]'
} puts eval("LocalTree" + yaml_vari)

In general, eval should be avoided. Try this:

def retrieve(*path)
path.inject(LocalTree) { |obj,key| obj[key] }
end

Call it as retrieve('This', 'Thing'), for your example.

--Greg

Thank you Greg.

I applied your suggestion to my application and it works.

In trying to further understand how .inject works, I looked in the
pickaxe book and found that this would cause (possibly many)
intermediate values to be retrieved (depending on YAML configuration)
while only the last value is returned. I ran a quick benchmark and the
..inject code was about 28% slower than using eval in my application.

This "slowdown" doesn't really matter, but I was thinking that perhaps
it could be significant if the YAML file size increased. But, if this
happens, perhaps I shouldn't be using YAML to store the data. :)

Do you know of a way to reduce the number of evaluations that occur
when using inject?

Also, can you give a quick pointer as to why eval should be avoided?

Thanks again for your reply.
Dale
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top