From: dara Date: 2009-12-04T08:41:30+09:00 Subject: Re: Variable references in yaml files Actually, thinking just a little further, your suggestion of merging hashes is probably the way to go. Similar to below, but instead of the convoluted substitution hash, I can just merge a hash of on-the-fly expected results with the hard-coded ones. So the solution doesn't really scratch my itch of hoping to keep all the expected results in one place, but I think I straightened out my thinking and learned something in the process. Thanks! On Dec 3, 3:54 pm, David Masover wrote: > On Thursday 03 December 2009 03:08:03 pm dara wrote: > > > The contents of sampl.yml are: > > :first: 'John' > > :second: 'Jane' > > :third: 'Jack' > > :fourth: "#{fourth_member}" > > In other words, you have a local variable fourth_member which you want to > appear there? > > > Can anyone > > either: > > 1) Show me a way to do this (much preferred ;) ). > > 2) Confirm this can't be done (would at least save me wasting further > > time on it). > > I can do both. > > I doubt very much that Yaml itself supports this, and it would be very > dangerous and scary if it does. > > However, you could easily do something like this yourself. The quick-and- > dirty, dangerous way would probably go something like this: > > hash.each_pair do |key, value| >   hash[key] = eval "\"#{value}\"" > end > > It should be obvious why this is dangerous, though -- that yaml file can now > contain arbitrary code, probably not what you want. But you get the idea -- > it's easy enough to build some kind of template system. Here's a safer way -- > first, don't use a local variable, use a hash of variables you want to make > available to the script: > > yaml_variables = {:fourth_member => 'Joan'} > > Then it's a simple matter of substitution: > > hash.each_value do |string| >   yaml_variables.each_pair do |key, value| >     string.gsub! "\#{#{key}}", value >   end > end > > Note that you're not constrained to the #{} syntax. You can make up your own. > > This still has some flaws -- for example, if you have something like this: > > yaml_variables = {:foo => '#{bar}', :bar => 'baz'} > > Depending what order you iterate through the yaml_variables hash, you might > get either the string '#{bar}' (probably what you wanted), or the string > 'baz', replacing any occurrence of '#{foo}'. > > There are other problems -- I'm assuming your yaml file is a single, flat hash > -- but I'm sure you can come up with something better. > > Also, it might be helpful to know what you're actually doing with this. It's > quite possible you don't need anything nearly this complex, and Yaml does have > some substitution of its own that might be handy -- though that's within a > file, it doesn't pull values out of your script. Also, if you're just trying > to define a default value, leave the value nil in the Yaml file, and merge it > into a hash of default values.