Dynamic method call

I'm trying, for the purpose of making something similar to a grammar, to do
this

if_a_condition_is_true(condition, "method_name(arg1, arg2)")

where

def method_name(arg1, arg2)
#do something
end

i've tried many way to implement

def if_condition_is_true(condition , action)
#such as
eval(action)
#or
call self.method(action)

end

but noone worked, i've trying googling a bit but no chances. Have you got an
idea on how to call dynamically a method, with his arguments?

Thanks a lot folks

···

--

Andrea Maschio

http://www.superandrew.it

A clever person solves a problem.
A wise person avoids it.

Einstein

To call an arbitrary method on an object use send

object.send( :method_name_as_symbol [, arg1, arg2 ...] )

You can put that in an if statement etc or use

object.send( :method ) if some_condition_is_true

HTH
Daniel

···

On 8/1/07, Andrea Maschio <andrea.maschio@gmail.com> wrote:

I'm trying, for the purpose of making something similar to a grammar, to
do
this

if_a_condition_is_true(condition, "method_name(arg1, arg2)")

where

def method_name(arg1, arg2)
#do something
end

i've tried many way to implement

def if_condition_is_true(condition , action)
#such as
eval(action)
#or
call self.method(action)

end

but noone worked, i've trying googling a bit but no chances. Have you got
an
idea on how to call dynamically a method, with his arguments?

Thanks a lot folks

--

Andrea Maschio

http://www.superandrew.it

A clever person solves a problem.
A wise person avoids it.

Einstein

I'm trying, for the purpose of making something similar to a grammar, to do
this

if_a_condition_is_true(condition, "method_name(arg1, arg2)")

where

def method_name(arg1, arg2)
#do something
end

i've tried many way to implement

def if_condition_is_true(condition , action)
#such as
eval(action)
#or
call self.method(action)

end

but noone worked, i've trying googling a bit but no chances. Have you got an
idea on how to call dynamically a method, with his arguments?

Hi,
I'm not sure of why you need to implement it like this, but that's up to you.
This works for me:

def if_condition_is_true(condition , action)
  eval(action) if condition
end

def method_name(arg1, arg2)
  puts arg1+ arg2
end

if_condition_is_true(true, "method_name(2, 3)")

Cheers,
Dave

Thank you very much guys, it worked. I was doing this for the purpose of
create a scripting language in my lang for testers to easy developing of use
case testing with watir.
For english people is probably easier to read

you really think that's easier to read than:

method_name(2,3) if condition

???

···

On 8/1/07, Andrea Maschio <andrea.maschio@gmail.com> wrote:

Thank you very much guys, it worked. I was doing this for the purpose of
create a scripting language in my lang for testers to easy developing of use
case testing with watir.
For english people is probably easier to read

Hi --

···

On Wed, 1 Aug 2007, Andrea Maschio wrote:

Thank you very much guys, it worked. I was doing this for the purpose of
create a scripting language in my lang for testers to easy developing of use
case testing with watir.
For english people is probably easier to read

Maybe, maybe not.... I would tend to say:

   if 5 is greater than 3

rather than

   if this condition is true: 5 is greater than 3

But of course it depends on the wider context you're developing.

David

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

the problem is that method_name is a static call, i need to make it dynamic
and choosed by the user/programmer, so at least he should type
eval("method_name(arg1,arg2)") if condition

but my aim was just to encapsulate this in a more comprehensible grammar
like

if_it_happens_that(is_true, "do_something(arg1,arg2)")

in another language that english it sound more different using english word
"like if, then, end, do"

i know it could sound weird, but this was my need, and i solved it with eval
(of course the internal logic is far more complex)

···

2007/8/1, Gregory Brown <gregory.t.brown@gmail.com>:

On 8/1/07, Andrea Maschio <andrea.maschio@gmail.com> wrote:
> Thank you very much guys, it worked. I was doing this for the purpose of
> create a scripting language in my lang for testers to easy developing of
use
> case testing with watir.
> For english people is probably easier to read

you really think that's easier to read than:

method_name(2,3) if condition

???

--

Andrea Maschio

http://www.superandrew.it

A clever person solves a problem.
A wise person avoids it.

Einstein

Andrea,

Hmm. A 'scripting language for testers' sounds like the RSpec
DSL[0]. Your cases should map to RSpec contexts very nicely.

Regards,

Paul.

[0] http://rspec.rubyforge.org/index.html

···

On 8/1/07, Andrea Maschio <andrea.masc...@gmail.com> wrote:

> Thank you very much guys, it worked. I was doing this for the purpose of
> create a scripting language in my lang for testers to easy developing of use
> case testing with watir.
> For english people is probably easier to read.

Yes, probably i started this post not imaging it would be difficult to
imagine a syntax mixed and merged from 2 language, but since most of you
people aren't speaking english as a first language, i think it would be easy
to imagine that for a tester(not a developer, but someone who will use my
'scripting language' built wrapping watir facilities) would be nicer and
easier to understand something like

se_presente_testo("inserimento effettuato", "registra('testUseCase123',
'completo'))

than

if presente_testo then blabla

or blabla if presente _testo

That was not he point, which was how to implement a dynamic call to a
method. The grammar stuff probably at beginning was just a subtilety, but it
slighty began to make me understand some underlying language mechanisms
that i believe are as powerful as easier compared to other language's
features.

So thanks a lot for the time to discuss about this, i really like this list
and i find it is truly live and active as a Ruby community should be! :slight_smile:

···

2007/8/3, dblack@rubypal.com <dblack@rubypal.com>:

Hi --

On Wed, 1 Aug 2007, Andrea Maschio wrote:

> Thank you very much guys, it worked. I was doing this for the purpose of
> create a scripting language in my lang for testers to easy developing of
use
> case testing with watir.
> For english people is probably easier to read

Maybe, maybe not.... I would tend to say:

   if 5 is greater than 3

rather than

   if this condition is true: 5 is greater than 3

But of course it depends on the wider context you're developing.

David

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

--

Andrea Maschio

http://www.superandrew.it

A clever person solves a problem.
A wise person avoids it.

Einstein

I still don't quite understand the problem you're tring to solve, but
consider using send(:method,arg1,arg2) instead of eval(). You're
begging for a mess using eval() to allow end users to input stuff.

···

On 8/1/07, Andrea Maschio <andrea.maschio@gmail.com> wrote:

the problem is that method_name is a static call, i need to make it dynamic
and choosed by the user/programmer, so at least he should type
eval("method_name(arg1,arg2)") if condition

but my aim was just to encapsulate this in a more comprehensible grammar
like

if_it_happens_that(is_true, "do_something(arg1,arg2)")

in another language that english it sound more different using english word
"like if, then, end, do"

i know it could sound weird, but this was my need, and i solved it with eval
(of course the internal logic is far more complex)

Do you want something like this :

···

Le jeudi 02 août 2007 à 04:27 +0900, Andrea Maschio a écrit :

the problem is that method_name is a static call, i need to make it dynamic
and choosed by the user/programmer, so at least he should type
eval("method_name(arg1,arg2)") if condition

but my aim was just to encapsulate this in a more comprehensible grammar
like

if_it_happens_that(is_true, "do_something(arg1,arg2)")

in another language that english it sound more different using english word
"like if, then, end, do"

i know it could sound weird, but this was my need, and i solved it with eval
(of course the internal logic is far more complex)

---
def sendif( args, &bloc )
  if args[:if]
    send args[:then].shift, *args[:then], &bloc
  else
    send args[:else].shift, *args[:else], &bloc if args[:else]
  end
end

sendif :if => 1 < 2, :then => [:p, "gagne"], :else => [:puts, "perdu"]
---
?

--
Etienne Vallette d'Osia

>
> > Thank you very much guys, it worked. I was doing this for the purpose of
> > create a scripting language in my lang for testers to easy developing of use
> > case testing with watir.
> > For english people is probably easier to read.

Andrea,

Hmm. A 'scripting language for testers' sounds like the RSpec
DSL[0]. Your cases should map to RSpec contexts very nicely.

Actually, we already have integration with Watir built into spec/ui
(available from http://rubyforge.org/frs/?group_id=797\). Admittedly it
is less mature than rspec as a whole, but I use it all the time to
drive in-browser testing.

Also, we're in the process of merging rbehave's story runner into
rspec to make rspec a full-stack bdd framework. It won't be long
before we're able to integrate that w/ spec/ui as well, in which case
you'll be able to write in-browser tests that look like this:

Scenario "anonymous user tries to access private page" do
  Given "an anonymous user" { ... }
  When "go to /private/page" { ... }
  Then "should redirect to /login" { ... }
end

Sadly, that's a few months off. Happily, that's JUST a few months off !

···

On 8/3/07, Paul Novak <novakps@gmail.com> wrote:

> On 8/1/07, Andrea Maschio <andrea.masc...@gmail.com> wrote:

Regards,

Paul.

[0] http://rspec.rubyforge.org/index.html

Thanks a lot, Paul, I'll take a look for sure

···

2007/8/3, Paul Novak <novakps@gmail.com>:

> On 8/1/07, Andrea Maschio <andrea.masc...@gmail.com> wrote:
>
> > Thank you very much guys, it worked. I was doing this for the purpose
of
> > create a scripting language in my lang for testers to easy developing
of use
> > case testing with watir.
> > For english people is probably easier to read.

Andrea,

Hmm. A 'scripting language for testers' sounds like the RSpec
DSL[0]. Your cases should map to RSpec contexts very nicely.

Regards,

Paul.

[0] http://rspec.rubyforge.org/index.html

--

Andrea Maschio

http://www.superandrew.it

A clever person solves a problem.
A wise person avoids it.

Einstein

What still bugs me is that you are using a dynamic call where there is no need.

It's entirely possible to write a method that allows you to do something like:

se_presenete_testo("inserimento effettuato") { registra 'testUseCase123' }

which would be one less language construct to reinvent.

···

On 8/3/07, Andrea Maschio <andrea.maschio@gmail.com> wrote:

Yes, probably i started this post not imaging it would be difficult to
imagine a syntax mixed and merged from 2 language, but since most of you
people aren't speaking english as a first language, i think it would be easy
to imagine that for a tester(not a developer, but someone who will use my
'scripting language' built wrapping watir facilities) would be nicer and
easier to understand something like

se_presente_testo("inserimento effettuato", "registra('testUseCase123',

Ok, Gregory, now i understand that i didn't explain very well. The only part
in wich the user (let's say a VERY junior programmer) is the scripting
interface i provide for him, so he will write
if_is_true(a_condition, "do_something(arg1,arg2)")

tha internal implementation is my matter, but if you think eval is bad (i
probably understand why), the solution with

send(:method,arg1,arg2)

is probably good, but how can i allow a user to input the method name with
his arguments? Anyway, i'm going to try.

···

2007/8/1, Gregory Brown <gregory.t.brown@gmail.com>:

On 8/1/07, Andrea Maschio <andrea.maschio@gmail.com> wrote:
> the problem is that method_name is a static call, i need to make it
dynamic
> and choosed by the user/programmer, so at least he should type
> eval("method_name(arg1,arg2)") if condition
>
> but my aim was just to encapsulate this in a more comprehensible grammar
> like
>
> if_it_happens_that(is_true, "do_something(arg1,arg2)")
>
> in another language that english it sound more different using english
word
> "like if, then, end, do"
>
> i know it could sound weird, but this was my need, and i solved it with
eval
> (of course the internal logic is far more complex)

I still don't quite understand the problem you're tring to solve, but
consider using send(:method,arg1,arg2) instead of eval(). You're
begging for a mess using eval() to allow end users to input stuff.

--

Andrea Maschio

http://www.superandrew.it

A clever person solves a problem.
A wise person avoids it.

Einstein

Damn, that's elegant!

  Bas

···

On Thu, Aug 02, 2007 at 04:48:30AM +0900, dohzya wrote:

Do you want something like this :
---
def sendif( args, &bloc )
  if args[:if]
    send args[:then].shift, *args[:then], &bloc
  else
    send args[:else].shift, *args[:else], &bloc if args[:else]
  end
end

sendif :if => 1 < 2, :then => [:p, "gagne"], :else => [:puts, "perdu"]
---
?

--
Bas van Gils <bas@van-gils.org>, http://www.van-gils.org
[[[ Thank you for not distributing my E-mail address ]]]

Quod est inferius est sicut quod est superius, et quod est superius est sicut
quod est inferius, ad perpetranda miracula rei unius.

Have you considered:

   if_is_true(condition) { do_something(...) }

?

That doesn't require eval() or send().

James Edward Gray II

···

On Aug 2, 2007, at 2:27 AM, Andrea Maschio wrote:

Ok, Gregory, now i understand that i didn't explain very well. The only part
in wich the user (let's say a VERY junior programmer) is the scripting
interface i provide for him, so he will write
if_is_true(a_condition, "do_something(arg1,arg2)")

tha internal implementation is my matter, but if you think eval is bad (i
probably understand why), the solution with

send(:method,arg1,arg2)

is probably good, but how can i allow a user to input the method name with
his arguments? Anyway, i'm going to try.

This may be slightly different, but I am calling a method dynamically
this way:

case tool
when "drill" then
   @operation = self.method(:drill) ;
when "cut" then
   @operation = self.method(:cut) ;
when "bend" then
   @operation = self.method(:bend) ;
end

@operation.call ; # call whatever method was set.

Todd

···

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

I dig it too, though I like better:

sendif 1 < 2, :then => [:p, "gagne"], :else => [:puts, "perdue"]

just because it kills the redundant if.

···

On 8/4/07, Bas van Gils <bas@van-gils.org> wrote:

On Thu, Aug 02, 2007 at 04:48:30AM +0900, dohzya wrote:
>
> Do you want something like this :
> ---
> def sendif( args, &bloc )
> if args[:if]
> send args[:then].shift, *args[:then], &bloc
> else
> send args[:else].shift, *args[:else], &bloc if args[:else]
> end
> end
>
> sendif :if => 1 < 2, :then => [:p, "gagne"], :else => [:puts, "perdu"]
> ---
> ?

Damn, that's elegant!

Alle giovedì 2 agosto 2007, Todd Burch ha scritto:

This may be slightly different, but I am calling a method dynamically
this way:

case tool
when "drill" then
   @operation = self.method(:drill) ;
when "cut" then
   @operation = self.method(:cut) ;
when "bend" then
   @operation = self.method(:bend) ;
end

@operation.call ; # call whatever method was set.

Todd

If the content of the tool variable are exactly the method names, then you
don't need the case statement:

  @operation = self.method(tool)
  @operation.call

Stefano