Ruby 1.8 vs 2.3 handling YAML config arrays differently - yaml

I'm trying to upgrade a server that has ruby scripts developed by another person. I'm a perl/php developer and no little about ruby, just trying to get the scripts to work that was developed with Ruby 1.8 and the scripts seems to behave differently handling arrays in the newer version. The script was not matching iterated folders with a config file array with the folder names and I believe I've boiled it down to the way the YAML config file is converted to an array. I put together this simple script:
require 'rubygems'
require 'yaml'
config_filename = File.expand_path(File.dirname(__FILE__) + "/testruby.yml")
#config = YAML.load(File.open(config_filename))
puts #config
The YAML testruby.yml config file looks like this:
1_01:
name: Monday Show
suffix: showM
program_id: 123
segment: 1
dated: false
1_02:
name: Monday Show
suffix: showM
program_id: 123
segment: 2
dated: false
1_03:
name: Tuesday Show
suffix: showT
program_id: 124
segment: 1
dated: true
When I run this on the original server with Ruby 1.8, the result is:
1_03program_id124nameTuesday Showsegment1suffixshowTdatedtrue1_02program_id123nameMonday Showsegment2suffixshowMdatedfalse1_01program_id123nameMonday Showsegment1suffixshowMdatedfalse
But when ran on the new server with Ruby 2.3 I get a array:
{101=>{"name"=>"Monday Show", "suffix"=>"showM", "program_id"=>123, "segment"=>1, "dated"=>false}, 102=>{"name"=>"Monday Show", "suffix"=>"showM", "program_id"=>123, "segment"=>2, "dated"=>false}, 103=>{"name"=>"Tuesday Show", "suffix"=>"showT", "program_id"=>124, "segment"=>1, "dated"=>true}}
It even removes the underscore from the folder name key in the config file. For this reason, later in the script, calls to #config[1_01] does not match of course. Is there a way to get the array to build like version 1.9 so the rest of the script works as designed?
One more thing to note, not sure if it related to the issue. The require 'yaml' line was not present in the script, I added after receiving this error when ran:
testruby.rb:4:in `<main>': uninitialized constant YAML (NameError)

Well, it seems all I had to do was enclose the YAML keys in quotes and now the hash object includes the underscore in the keys and the rest of the script works!

Related

Replacing variable value in ruby while setting the value using "set" command

I have a .properties files as below:
user:abcd
pwd:xyz
system:test
Next, I have a ruby script with Watir for browser automation. In this script, I have statements like
browser.text_field(:id => 'identifierId').set "#{user}:variable to be replaced by its value from .properties file".
Similarly, other values need to be replaced for "pwd" and "system".
I tried the solution per below posts:
Replace properties in one file from those in another in Ruby
However, "set" command is setting whatever has been paased as arguments to it instead of replacing the variable with its value.
Please help.
You have to read the information out of the file.
Most Watir users leverage yaml files for this.
config/properties.yml:
user: abcd
pwd: xyz
system: test
Then read the yaml file & parse your data:
properties = YAML.safe_load(IO.read('config/properties.yml'))
text_field = browser.text_field(id: 'identifierId')
text_field.set properties['user']
Alternately you can take a look at Cheezy's Fig Newton gem, which is designed to work with his Page Object gem

How to write a file that is both valid ruby syntax and valid YAML syntax

In order to have only a single point of configuration for my app I need to make a YAML config file that is also valid ruby code. I.e. a mixed syntax file that can be parsed as YAML and parsed as ruby.
My application is a suite of processes managed by the god gem. I want to load a new group of maintained processes (watches) for each new configuration file.
God allows loading a new app.god (ruby) file with new watches defined, but I don't want an app.god and app.yml, just one file. Simplest might be to just have the app.god file and include the configuration within that, but I preferred the idea of a yml file that was also valid ruby code.
#I found this that might be helpful:
#This is a valid ruby and a valid YAML file
#Comments are the same in YAML and ruby
true ?true:
- <<YAML.to_i
# At this point in ruby it is the contents of a here doc (that will be
# converted to an integer and negated if true happens not to be true)
# In YAML it is a hash with the first entry having key "true ?true"
# representing a list containing the string "- <<YAML.to_i"
# If your YAML object should be a list not a hash you could remove the first line
any_valid_yaml: from here
a_list:
- or
- anything
- really
#Then mark the end of the YAML document with
---
#And YAML is done and ignores anything from here on
#Next terminate the ruby here document
YAML
#Now we're in ruby world
#this = "pure ruby"
def anything(ruby)
"here"
end

ruby to_yaml 2.0.0 adds !ruby/object:Hash but YAML.load won't read it

Is there a way to disable ruby 2.0.0 YAML's suffixing with ruby type info?
I just upgraded to ruby 2.0.0 and I'm having YAML problems. I read-update-write a yaml file that previously looked like this
test:
test2:
somevar: hello
When I feed this into ruby 200, it reads OK but writes:
test: !ruby/object:Hash
test2: !ruby/object:Hash
somevar: hello
When I rerun the program YAML.load reads nothing.
myH = YAML.load_file( YAML_FPATH )
puts "Yaml as Hash:" + myH.inspect
>> Yaml as Hash: {}
Curiously, if I pass the "test: !ruby/object:Hash" version of the file to ruby 1.8.7, it reads the suffixed file OK and writes a non-suffixed file.
Problem found: I modified hash.to_yaml so that it sorts the keys. Since my code is based on hash.to_yaml 1.8.7 I need to revise it based on hash.to_yaml 2.0.0.

Replace properties in one file from those in another in Ruby

I want to replace properties in one file from those in another. (I am new to ruby, and read about Ruby and YAML. I have a Java background)
Eg.
File 1
server_ip_address=$[ip]
value_threshold=$[threshold]
system_name=$[sys_name]
File 2
ip=192.168.1.1
threshold=10
sys_name=foo
The ruby script should replace the $ values by their real values (I do not know if $[] is the format used in ruby. Also do Files 1 and 2 have to be YAML files, or erb files?) and produce File 1 as :
server_ip_address=192.168.1.1
value_threshold=10
system_name=foo
I searched the web for this, but could not express it in the right keywords to find a solution/pointer to a solution/reference material on google. How can this be done by a ruby script?
Thanks
If you can switch the formats, this should be as easy as:
require 'yaml'
variables = YAML.load(File.open('file2.yaml'))
template = File.read('file1.conf')
puts template.gsub(/\$\[(\w+)\]/) { variables[$1] }
Your template can stay as-is, but the substitution file would look like:
ip: 192.168.1.1
threshold: 10
sys_name: foo
This makes it easy to read in using the YAML library.

Ruby Hash.has_key? returning false for the first key on Windows

I'm having a weird issue with Ruby hashes on windows. I'm loading the following YAML file and parsing it as a hash:
tasks:
- clone_skeleton, <skeleton_path>
- summit_capify, <skeleton_path>
I'm using YAML.load() to load the file into a hash. If I print out hash.keys tasks is listed as a key but if I do hash.has_key?("tasks") I get back false. However if I change the yaml to this
directory_structure:
tasks:
- clone_skeleton, <skeleton_path>
- summit_capify, <skeleton_path>
hash.has_key?("tasks") returns true but hash.has_key?("directory_structure") returns false. I haven't tested in Linux but I don't seem to be having this problem on OS X, just Windows. I'm using Ruby 1.9.2 and have tested in Cygwin and using the standard command prompt.
I don't know if this is a ruby bug, a problem with my YAML or something else. Any ideas?
UPDATE: Looks like this is fixed in Ruby 1.9.3
Is it possible the keys are Symbols and not Strings? Trying has_key?(:tasks).
Whenever you're debugging, don't do puts hash.keys, but do puts hash.keys.inspect - the latter indicates exactly what's going on.
Or you may want to do puts hash.inspect.

Resources