Voss Voss - 1 month ago 5
Ruby Question

How do I turn a string into the name of an array?

I've think I've created multiple arrays from strings but if I try to inspect the array I receive an error.

File.open("livestock.txt", "r") do |file|
file.readlines.each do |x|

if x.match(/:*:/)
# puts x.inspect
# strip string
x.gsub!(/[^A-Za-z]/, '')
puts x.inspect
x = Array.new(){Hash.new}
# puts x.inspect
# puts "no"


animals.rb:12:in `block (2 levels) in <main>': undefined local variable or method `pigs' for main:Object (NameError)
from animals.rb:2:in `each'
from animals.rb:2:in `block in <main>'
from animals.rb:1:in `open'
from animals.rb:1:in `<main>'

Ideally I want to create pigs =[]
then add hashes to this array such as:

pigs = [{"name"=>"peggy", "id"=>1, "owner"=>"wolcott farms"},
{"name"=>"sue", "id"=>2, "owner"=>"blue moon farms"},
{"name"=>"eddie", "id"=>3, "owner"=>"sunrise farms"}

and the same for cows, etc.

my text file animals.txt is

name, id, owner
peggy, 1, wolcott farms
sue, 2, blue moon farms
eddie, 3, sunrise farms

name, id, owner
dee, 3, black hat farms
sunny, 2, blue moon farms
bess, 4, wolcott farms


Parse Text, Then Assign Using Instance Variables

You can't use local variables, but you can use Object#instance_variable_get and Object#instance_variable_set to do this kind of metaprogramming. For example:

str     = File.read '/tmp/livestock.txt'
records = str.split /\n\n+/
records.map! { |r| r.split /\n/ }
records.map do |r| 
  var    = ?@ << r.shift.strip.delete(?:)
  fields = r.shift.strip.scan /[^,]+/
  hashes = r.map { |e| e.split(?,).flat_map &:strip }.
             map { |e| fields.zip e }.
             map &:to_h
  instance_variable_set var,

# The data is now stored correctly in the following instance variables.


Note that if @pigs or @cows already exist because you're testing in the REPL, your results may not be what you expect. Make sure you invoke Object#remove_instance_variable, set your variables to nil, or create a new instance of your class between tests.