-1

This might be hard to explain, but I'll try.

Let's say I have a text file containing:

variable one
I'm variable 2
300
False
I am variable 5

Let's assume that I have multiple files like this and I don't know what is in each file. I want to take each line in the file and put it into a variable.

For example, this file would become these variables (which I can sort into strings, numbers and booleans with if statements):

var1 = "variable one"
var2 = "I'm variable 2"
var3 = 300
var4 = False
var5 = "I am variable 5"

I want to make sure that this can be applied to any file with any number of lines.

Here's an example of what I hope the code would look like:

File.open("file.txt").each do |line|
  var.new = "var" + line.line_number #creates new variable named "var" and the line number
var = line
end

I hope someone understands and knows how to do this because I'm completely stumped. I feel like there's some sort of really simple solution here that everybody commonly knows and I'm missing it or I just don't know it.

Thanks, Reece

notsoscottishscot
  • 350
  • 1
  • 4
  • 11
  • 1
    What do you intend to do with them afterwards? You cannot dynamically create local variables but depending on your end goal there are lots of ways to implement this – engineersmnky Aug 21 '18 at 20:12

3 Answers3

1

This answers your question, but context is certainly required to do this in a way that actually matters to your application.

This isn't necessarily the only way, or even the "best" way, but it's the most straightforward in my opinion:

File.read("file.txt").split("\n").each_with_index do |line, index|
  instance_variable_set("@var#{index}", line) 
end

@var0 #variable one
@var1 #I'm variable 2

If you want to convert False and 300 from a string — which is how it's read from the file — to a ruby object, you'd have to do some manual parsing. Say,

def content_for_line(line)
  if line == 'False'
    return false
  end
  if line.to_s == line.to_i.to_s
    return line.to_i 
  end
  line
end

...

instance_variable_set("@var#{index}", content_for_line(line)) 

Maybe you only want to read the file as an array though.

array = File.read("file.txt").split("\n")

array[0] #variable one
Josh Brody
  • 5,153
  • 1
  • 14
  • 25
0

It feels like you really want an array here. To that end you can read the file directly into an array, one entry per line:

array_of_lines = File.readlines("file.txt")
array_of_lines[0]
=> "variable one\n"
array_of_lines[1]
=> "300\n"

etc

elliotcm
  • 760
  • 4
  • 7
0

You could implement this as as class with built in parsing logic (I only handled the given example):

class VarGroup
  attr_reader :vars
  def initialize(file_name)
    @vars = File.foreach(file_name).map do |l|
      if l =~ /(True|False)/i
        l.match?(/True/i)
      else  
        begin  
          Integer(l)
        rescue ArgumentError 
          l.strip
        end  
      end
    end
  end

  def method_missing(method_name,*args,&block)
    if method_name =~ /var(\d+)/ && $1.to_i.nonzero? && $1.to_i <= vars.size
      @vars[$1.to_i - 1] 
    else 
      super
    end
  end
end 

Then it can be called like

v = VarGroup.new('test.txt')
v.vars 
#=> ["variable one", "I'm variable 2", 300, false, "I am variable 5"]
(1..6).each do |n|
  p v.public_send("var#{n}")
end
# "variable one"
# "I'm variable 2"
# 300
# false
# "I am variable 5"
# undefined method `var6' for #<VarGroup:0x000055a23e2f64e0>
engineersmnky
  • 25,495
  • 2
  • 36
  • 52