codeObserver
codeObserver

Reputation: 6647

Passing all arguments at once to a method

I am trying to read arguments from a text file and the pass them all at once to a Ruby method. The arguments in the text file are properly formatted e.g.:

"path", ["elem1","elem2"], 4,"string"

I intend to make a function call like this:

my_method("path", ["elem1","elem2"], 4,"string")

This hopefully I am trying to achieve like this:

  IO.readlines("path").each do |line|
    puts "#{line}"
    my_method(*line.split(","))
  end

The problem is that in the method all the array elements are wrapped in quotes. So my method ends up getting this:

""path"", "["elem1","elem2"]", "4",""string""

Now, this is probably because its an array of strings, but why wrap it with an additional "" when I say *arr?

If I use eval:

 IO.readlines("path").each do |line|
    puts "#{line}"
    my_method(*eval(line))
  end

I end up with syntax error, unexpected ',' after the first argument in "path", ["elem1","elem2"], 4,"string"

  1. How do I achieve passing all the elements to the method at once reading the arguments from a text file

  2. Also since Ruby does not care about types, why do I have to wrap my arguments with "" in the first place. If I don't wrap the argument in a quote, I get undefined variable for main:object error.

Upvotes: 0

Views: 563

Answers (2)

Paulo Henrique
Paulo Henrique

Reputation: 1025

IO.readlines("path").each do |line|
    params = line.split(",").each do |param|
        param = eval(param)
    end
    my_method(*params)
end

When you read the line, all params are strings, so to get arrays and integers you might try to eval then first.

  1. the eval tip might be enough to fix your code.

  2. if you pass the param without quotes, the interpreter will understand it as a constant and not as a string. Thats why you get undefined variable. Again, the eval tip should solve this.

OBS: Be careful with eval since it will execute any code, a command to erase the file or even worse (like mess with your computer or server) if the person behind the source of that file knows it.

Upvotes: 0

Manish Das
Manish Das

Reputation: 3893

I have one solution, but instead of using "," as your delimiter use some other special character as delimiter in the input line.

# Input line in somefile.txt delimited by "||" :
#    "path" || ["elem1","elem2"] || 4 || "string"   


def my_method(arg1, arg2, arg3, arg4)
  path = arg1
  arr = arg2.gsub(/([\[\]])/, "").split(",")
  number = arg3.to_i
  string = arg4
  puts "path    : #{path} and is #{path.class}"
  puts "arr     : #{arr} and is #{arr.class}"
  puts "number  : #{number} and is #{number.class}"
  puts "string  : #{string} and is #{string.class}"
end

IO.readlines("somefile.txt").each do |line|
  my_method(*line.gsub(/[(\\")]/, " ").split("||"))
end

I hope this helped you out. Let me know if you have any problem.

Upvotes: 1

Related Questions