Unable to adjust Ruby block - ruby

I am fairly new to Ruby, JRuby, etc...
I started to work on migration of certain bash scripts into Ruby, now I used a block from a different pipeline, but here its unnecessary to use it in this format as there is no need to iterate through array:
all_cf = %w(
customers
).map do |table_name|
schema("columns.#{table_name}.hbase.families").gsub(/'/,'')
end.uniq.map{|s| "{ NAME => '#{s}', VERSIONS => 1 }" }.join(',')
Is there an easier way to replace that array iteration and just replace #{table_name} with customers?
I tried this:
all_cf = task do
schema("columns.customers.hbase.families").gsub(/'/,'')
end.uniq.map...
But that just throws error and tried couple of more forms of this, but I think I still don't have a right understanding of the Ruby grammar, as I come from the PHP background I'm still struggling with this, anyone any idea how, and maybe an explanation why?
Cheers...

This produces the result that your original script produced:
"{ NAME => '#{schema("columns.customers.hbase.families").gsub(/'/,'')}', VERSION => 1 }"
I'm not sure what task is, so I don't know whether you should expect your code to work. uniq is a method on Array which returns an Array with all duplicates removed:
> [1,2,3,1,2,1].uniq
# => [1,2,3]
Similarly you can look up what map and join do.

Related

How do I best dump a Psych::Nodes::Document back to a YAML string?

This does what I want, but going via to_ruby seems unnecessary:
doc = Psych.parse("foo: 123")
doc.to_ruby.to_yaml
# => "---\nfoo: 123\n"
When I try to do this, I get an error:
DEV 16:49:08 >> Psych.parse("foo: 123").to_yaml
RuntimeError: expected STREAM-START
from /opt/…/lib/ruby/2.5.0/psych/visitors/emitter.rb:42:in `start_mapping'
I get the impression that the input needs to be a stream of some sort, but I don't quite get what incantation I need. Any ideas?
(The problem I'm trying to solve here, by the way (in case you know of a better way) is to fix some YAML that can't be deserialised into Ruby, because it references classes that don't exist. The YAML is quite complex, so I don't want to just search-and-replace in the YAML string. My thinking was that I could use Psych.parse to get a syntax tree, modify that tree, then dump it back into a YAML string.)
Figured out the incantation after finding the higher-level docs at https://ruby-doc.org//stdlib-2.3.0_preview1/libdoc/psych/rdoc/Psych/Nodes.html, though please let me know if there's a better way:
doc = Psych.parse("foo: 123")
stream = Psych::Nodes::Stream.new
stream.children << doc
stream.to_yaml
# => "foo: 123\n"

How to compare data in two CSV files

I have two CSV files which have the same structure and ideally should have the same data.
I want to compare the data in them using Ruby and wanted to know if we already have a Ruby function for the same.
If you want to check whether files are identical you can simply use identical? which is an alias for compare_file:
FileUtils.identical?('file1.csv', 'file2.csv')
If you want to see the differences you might want to use diffy:
gem install diffy
puts Diffy::Diff.new('file1.csv', 'file2.csv', :source => 'files')
It produces diff-like output which can be nicely formatted as HTML:
puts Diffy::Diff.new('file1.csv', 'file2.csv', :source => 'files').to_s(:html_simple)
As Summea commented, look at the CSV class.
Then use:
#Will store each line of each file as an array of fields (so an array of arrays).
file1_lines = CSV.read("file1.csv")
file2_lines = CSV.read("file2.csv")
for i in 0..file1_lines.size
if (file1_lines[i] == file2_lines[i]
puts "Same #{file1_lines[i]}"
else
puts "#{file1_lines[i]} != #{file2_lines[i]}"
end
end
Note that using for in Ruby is quite rare. You normally iterate using an each on the collections, but there are two of them here.
Also, pay attention that one of the list may be longer than the other, but this should get you started.

RUBY/WATIR/RASTA: Pass the value from the excel/rasta to an array in Ruby?

How to pass the value separated with comma from the excel/rasta to an array in Ruby.
html looks like this,
....
<li><input type="checkbox" name="order:1" />Burger</li>
<li><input type="checkbox" name="order:2" />Pasta</li>
<li><input type="checkbox" name="order:3" />Fries</li>
...
EXCEL looks like this...
Orders
Burger, Pasta
this code doesnt work
attr_accessor :orders
order = [#orders]
order.each do |i|
.......
........
It should look like this in ruby...
attr_accessor :orders
orders = [ 'burger','pasta '] *#should pass data from excel in the array "**orders**"
orders.each do |i|
#browser.checkbox(:text => i).click
#browser.button(:name => 'save').click
end
So how would i do the passing of the value in excel to an array?
Sorry, I'm still learning Ruby :|
There is a favored library called roo. In the linked page, it will tell you how to install the library, then use it to get values out of excel.
require 'rubygems'
require 'roo'
HOURLY_RATE = 123.45
oo = Openoffice.new("simple_spreadsheet.ods")
oo.default_sheet = oo.sheets.first
oo.first_row.upto(oo.last_row) do |line|
#browser.check(:value => oo.cell(line,'A'))
#browser.button(:name => 'save').click
end
i can get the values in the excel but i don't know how will I drop them as array in Ruby
My code looks like this.. but it doesn't work
......
if array
arrayLabel = [:array]
arrayLabel.each do |i|
#browser.checkbox(:text => i).click
#browser.button(:name => 'save').set
end
end
..............
:array , is the column name where i get the value to be pass in ruby
And also How to do if when the data in the array is not found on the list of checkbos choices?
Find some online tutorials for Ruby, or purchase and work your way through a book like Everyday Scripting With Ruby.
Everyone has to start someplace, but at the moment, it seems you understand so little, and are over-reaching your abilities to the extent that the people who are trying to help you can barely make sense out of your question or what you are trying to do.
Next, work in baby steps, so you can tell what is working and what is failing, and gradually work your way up to what you want to do.
For example, in your case, get the Roo gem installed, and figure out how to use it to read from your spreadsheet and just print stuff on the screen.
Once you can do that, Then try to read the infomation into an array, and print the array out to the screen (so you know stuff got where you need it to go)
Now, write come code using Watir that has values hardcoded to click things etc and fill out the form you are working on etc.
Once you know that is working, combine that with your code to read the spreadsheet into an array, and replace the hard-coded values with stuff pulled from the array that you made from the spreadsheet.

Ruby parse comma separated text file

I need some help with a Ruby script I can call from the console. The script needs to parse a simple .txt file with comma separated values.
value 1, value2, value3, etc...
The values needs to be added to the database.
Any suggestions?
array = File.read("csv_file.txt").split(",").map(&:strip)
You will get the values in the array and use it to store to database. If you want more functions, you can make use of FasterCSV gem.
Ruby 1.9.2 has a very good CSV library which is useful for this stuff: http://www.ruby-doc.org/stdlib/libdoc/csv/rdoc/index.html
On earlier versions of Ruby you could use http://fastercsv.rubyforge.org/ (which essentially became CSV in 1.9.2)
You could do it manually by reading the file into a string and using .split(',') but I'd go with one of the libraries above.
Quick and dirty solution:
result = []
File.open("<path-to-file>","r") do |handle|
handle.each_line do |line|
result << line.split(",").strip
end
end # closes automatically when EOF reached
result.flatten!
result # => big array of values
Now you can iterate the result array and save the values to the database.
This simple file iteration doesn't take care for order or special fields, because it wasn't mentioned in the question.
Something easy to get you started:
IO.readlines("csv_file.txt", '').each do |line|
values = line.split(",").collect(&:strip)
# do something with the values?
end
Hope this helps.

How to assert on number of html table rows in ruby using capybara + cucumber

I am trying to get to grips with BDD web development in Ruby using cucumber + capybara and I am stuck at what should be an easy task - just to check the number of rows in a table. The intention of what I'm trying to achieve is something along the lines of:
page.should have_xpath("//table[#id='myTable']")
find("//table[#id='myTable']/tr").length.should == 3
But this doesn't work (missing method length) and I can't find a way to assert against the table length.
Any ideas anyone (please be easy on me tho' I'm a ruby nooby)
Thanks in advance
Neil
Even though have_css? will do the trick, your tests should tell you how they failed, rather than just saying some condition was supposed to be true and it was false. With this in mind, the first example below reads much better than the second:
# IF FAILED => "expected 10, got 7"
page.all('table#myTable tr').count.should == 10
# IF FAILED => "expected true, got false"
page.should have_css("table#myTable tr", :count=>10)
I think you can do this:
page.should have_css("table#mytable tr", :count=>3)
For some reason "has_css" does not work for me, however "all(selector)" works really wel
all("table#movies tr").count
I went with this in the end:
Then /^I should see "(.*)" once$/ do |text|
within_table('myTable') do
should have_xpath("//tr", :text => text, :count => 1)
end
end
which seemed suitably elegant.
I realise the other answers work but this seems to read well.
Any comments?
The method #find only returns one element (I think it just returns the first one if there are several matches) so you don't get a #length method because the result of #find is a Node not an Array.
To prove this to yourself, try
puts find("//table[#id='myTable']/tr").class
What you want is #all, which will return you an Array of all the matching nodes.
In this way you can learn the number of lines in the html table.
area = find_by_id('#areaID').all('tr').size
Assume that there are columns at the beginning of the table.You can reach the actual number in this way.
area = area-1

Resources