# How to make "generic" YAML calls?

**URL:** <https://rubytalk.org/t/how-to-make-generic-yaml-calls/33357>\
**Category:** ruby-talk\
**Created:** [30 November 2006 23:05 UTC](https://rubytalk.org/t/how-to-make-generic-yaml-calls/33357 "2006-11-30T23:05:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dale\_Quigg](https://avatars.discourse-cdn.com/v4/letter/d/cab0a1/32.png) [@Dale\_Quigg](https://rubytalk.org/u/Dale_Quigg)\
**Post date:** [30 November 2006 23:05 UTC](https://rubytalk.org/t/how-to-make-generic-yaml-calls/33357/1 "2006-11-30T23:05:07Z")

</div>

Hi,

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

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

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

Any hints/tips appreciated.

Thanks,  
Dale

---

<div class="post-metadata">

**Author:** ![Dale\_Quigg](https://avatars.discourse-cdn.com/v4/letter/d/cab0a1/32.png) [@Dale\_Quigg](https://rubytalk.org/u/Dale_Quigg)\
**Post date:** [30 November 2006 23:45 UTC](https://rubytalk.org/t/how-to-make-generic-yaml-calls/33357/2 "2006-11-30T23:45:05Z")

</div>

\<snip\>

> However, I want to write a class where I pass something like  
> &nbsp;&nbsp;'["This"]["Thing"]'  
> or  
> &nbsp;&nbsp;'["That"]["Thing"]'  
> and then make a call like;  
> &nbsp;&nbsp;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)

> **···**
>
> dale.quigg@aspentech.com wrote:

---

<div class="post-metadata">

**Author:** ![Gregory\_Seidman](https://avatars.discourse-cdn.com/v4/letter/g/eb9ed0/32.png) [@Gregory\_Seidman](https://rubytalk.org/u/Gregory_Seidman)\
**Post date:** [1 December 2006 13:59 UTC](https://rubytalk.org/t/how-to-make-generic-yaml-calls/33357/3 "2006-12-01T13:59:30Z")

</div>

} \<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)  
&nbsp;&nbsp;path.inject(LocalTree) { |obj,key| obj[key] }  
end

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

--Greg

> **···**
>
> On Fri, Dec 01, 2006 at 08:45:05AM +0900, [dale.quigg@aspentech.com](mailto:dale.quigg@aspentech.com) wrote:  
> } [dale.quigg@aspentech.com](mailto:dale.quigg@aspentech.com) wrote:

---

<div class="post-metadata">

**Author:** ![Dale\_Quigg](https://avatars.discourse-cdn.com/v4/letter/d/cab0a1/32.png) [@Dale\_Quigg](https://rubytalk.org/u/Dale_Quigg)\
**Post date:** [4 December 2006 20:20 UTC](https://rubytalk.org/t/how-to-make-generic-yaml-calls/33357/4 "2006-12-04T20:20:08Z")

</div>

Gregory Seidman wrote:

> } \<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)  
> &nbsp;&nbsp;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

> **···**
>
> > On Fri, Dec 01, 2006 at 08:45:05AM +0900, dale.quigg@aspentech.com wrote:  
> > } dale.quigg@aspentech.com wrote:
