Help- Converting String to a Method Call

I am new to Ruby. I'm trying to convert a string to a method call in
Ruby. I intend to store all my function calls in an Excel Worksheet and
use the extracted strings to make the actual method call. But I am not
able to convert the string obtained from the excel and use it as a
function call. I read somewhere that the Send() method helps convert
strings to method calls. But I am not able to use it correctly. For the
code mentioned below I obtain a "in `<top (required)>': undefined method
`Execute_Statement(5)' for main:Object (NoMethodError)"

···

************************************************************************************
begin
           def Execute_Statement(var1)
    puts("Hello",var1)
  end
end

x='Execute_Statement(5)' #This would be fed from the Excel Worksheet

send(x)

************************************************

What am I doing wrong ?

--
Posted via http://www.ruby-forum.com/.

Excerpts from Pradeep Pai's message of 2014-01-24 08:54:27 +0100:

I am new to Ruby. I'm trying to convert a string to a method call in
Ruby. I intend to store all my function calls in an Excel Worksheet and
use the extracted strings to make the actual method call. But I am not
able to convert the string obtained from the excel and use it as a
function call. I read somewhere that the Send() method helps convert
strings to method calls. But I am not able to use it correctly. For the
code mentioned below I obtain a "in `<top (required)>': undefined method
`Execute_Statement(5)' for main:Object (NoMethodError)"

************************************************************************************
begin
           def Execute_Statement(var1)
    puts("Hello",var1)
  end
end

x='Execute_Statement(5)' #This would be fed from the Excel Worksheet

send(x)

************************************************

What am I doing wrong ?

The problem lies in the fact that send needs the name of the method as first
argument and the arguments to be passed to the method as separate arguments. In
your case, it should be:

send 'Execute_Statement', 5

You need to find a way to split the name of the method ('Execute_Statement')
from its arguments, split the arguments (if there are more than one) and
converting them to the correct class. How to do so depends on your actual needs.
In the simple example you posted, you can use a Regexp:

string = 'Execute_Statement(5)'
match = string.match(/([^(]+)\((\d+)/)
name = match[1]
arg = match[2].to_i

send name, arg

For more information about Regexp, see the ri documentation for Regexp and
MatchData.

I hope this helps

Stefano

Thank you for the response Stefano,
I decided to provide the function name in the first column of the excel
and the parameters in the remaining columns of that row. The problem I
am facing currently is that I will be sending multiple functions(having
varying number of parameters) in the first column of my excel and I need
my code to pick these parameters and send these along with the function
name in the Send method. Could you suggest an approach for this need ?

···

--
Posted via http://www.ruby-forum.com/.

HI Jesus,
       I too am facing the same issue. Could you please explain a sample
code of how to get all the columns and place it in an array. Also, wats
does args* do.

···

--
Posted via http://www.ruby-forum.com/.

hi Jesus,
   Thank you for replying promptly for my query.This is my code,

require 'watir-webdriver'
require 'rspec/expectations'
require 'spreadsheet'
Spreadsheet.client_encoding = 'UTF-8'
book = Spreadsheet::Workbook.new
book = Spreadsheet.open 'path to my excel'

@browser = Watir::Browser.new :firefox
@browser.goto "testurl"

def textbox(obj_name, obj_value)
  @browser.text_field(:id => obj_name).set(obj_value)
end

sheet = book.worksheet(0)

sheet.each do |row|
  send row[0],row[1],row[2]
end

This is what i am using. My excel spreadsheet has three column for the
above example. But i will be calling many functions from the same excel
each having varying number of parameters. How will i implement this.

···

--
Posted via http://www.ruby-forum.com/.

you can use eval and binding :

csv=<<EEND
;;foo(2);;
;;fee(3,4,5);;
EEND

class Excel
  def foo(n) p ['foo',n] ; @foo||= ; @foo << n end
  def fee(*n) p ['fee',n]; @fee||= ; @fee << n end
  def get_binding() binding() end
  def rapport() puts "**** rapport ***";p @foo||; p @fee|| end
end

excel=Excel.new
bind=excel.get_binding

csv.split(/\r?\n/).each { |line|
line.split(';').each { |cell| eval(cell,bind) }
}
excel.rapport

Execution :

ruby excel.rb

["foo", 2]
["fee", [3, 4, 5]]
**** rapport ***
[2]
[[3, 4, 5]]

···

--
Posted via http://www.ruby-forum.com/\.

hi jesus,

    i tried using *row, but i get an error saying wrong number of
arguments.(4 for 2)(argument error)

···

--
Posted via http://www.ruby-forum.com/.

You could read all columns until you get to an empty one, place them
all in an array and call:

send name, *args

Jesus.

···

On Fri, Jan 24, 2014 at 12:28 PM, Pradeep Pai <lists@ruby-forum.com> wrote:

Thank you for the response Stefano,
I decided to provide the function name in the first column of the excel
and the parameters in the remaining columns of that row. The problem I
am facing currently is that I will be sending multiple functions(having
varying number of parameters) in the first column of my excel and I need
my code to pick these parameters and send these along with the function
name in the Send method. Could you suggest an approach for this need ?

What API are you using to read from an excel? As I don't know I'll
show an example with plain text.
Say you have this:

row = "method, arg1, arg2, arg3, arg4"
send *row.split(",")

For example:

2.0.0p195 :007 > s = "puts, a, b, c, d, e"
=> "puts, a, b, c, d, e"
2.0.0p195 :008 > send *s.split(",")
a
b
c
d
e

But also, as Stefano pointed out, if you have different types in the
Excel, like integers, floats, etc that your method expects as such,
you will have to convert them before calling the method.

Hope this helps,

Jesus.

···

On Fri, Jan 24, 2014 at 1:10 PM, Nandish Shetty <lists@ruby-forum.com> wrote:

HI Jesus,
       I too am facing the same issue. Could you please explain a sample
code of how to get all the columns and place it in an array. Also, wats
does args* do.

Looking a little bit at the spreadsheet gem, it seems that the Row
class inherits from Array, so you should be able to do this:

sheet.each do |row|
  send *row
end

but I haven't tested it.

Jesus.

···

On Fri, Jan 24, 2014 at 1:29 PM, Raju Ruby <lists@ruby-forum.com> wrote:

hi Jesus,
   Thank you for replying promptly for my query.This is my code,

require 'watir-webdriver'
require 'rspec/expectations'
require 'spreadsheet'
Spreadsheet.client_encoding = 'UTF-8'
book = Spreadsheet::Workbook.new
book = Spreadsheet.open 'path to my excel'

@browser = Watir::Browser.new :firefox
@browser.goto "testurl"

def textbox(obj_name, obj_value)
  @browser.text_field(:id => obj_name).set(obj_value)
end

sheet = book.worksheet(0)

sheet.each do |row|
  send row[0],row[1],row[2]
end

This is what i am using. My excel spreadsheet has three column for the
above example. But i will be calling many functions from the same excel
each having varying number of parameters. How will i implement this.