Passing math method to another method?


#1

I’m trying to figure out how to pass methods such as:
+, -, **, ^
to a method and evaluate.

For example,

def test(a, b, to_do)
return a.send(to_do(b))
end

puts test(1, 2, “+”) #should return 3
puts test(3, 3, “^”) #should return 0
puts test(3, 3, “**”) #should return 27

any help would be appreciated.


#2

On Jan 17, 2007, at 8:10 AM, Neutek wrote:

puts test(1, 2, “+”) #should return 3
puts test(3, 3, “^”) #should return 0
puts test(3, 3, “**”) #should return 27

any help would be appreciated.

def test(a, b, meth)
a.send(meth, b)
end
=> nil

test(1, 2, :+)
=> 3

test(3, 3, :^)
=> 0

test(3, 3, :**)
=> 27

Hope that helps.

James Edward G. II


#3

On Jan 17, 2007, at 3:10 PM, Neutek wrote:

puts test(1, 2, “+”) #should return 3
puts test(3, 3, “^”) #should return 0
puts test(3, 3, “**”) #should return 27

a.send(to_do, b)


#4

On 17.01.2007 15:06, Neutek wrote:

puts test(1, 2, “+”) #should return 3
puts test(3, 3, “^”) #should return 0
puts test(3, 3, “**”) #should return 27

any help would be appreciated.

Several ways to do it

irb(main):001:0> def test(a,b,op) a.send(op,b) end
=> nil
irb(main):002:0> test 1,2,:"+"
=> 3
irb(main):003:0> def test(a,b,op) a.send(op.to_sym,b) end
=> nil
irb(main):004:0> test 1,2,"+"
=> 3
irb(main):005:0> def test(a,b,op) op[a,b] end
=> nil
irb(main):006:0> test 1,2,lambda {|x,y| x+y}
=> 3

The last sample shows the more functional approach.

What are you trying to achieve?

Kind regards

robert


#5

Wow. Thanks for the input guys.

Robert, I was actually reading the summation wiki and they had a few
code examples in C++/Java… I thought I’d goof a bit and write
something out in ruby. Of course, I hit the roadblock when trying to
pass math operators(or methods rather) to a method…

I got this far :wink:

def sigma(floor, to_do, cap)

end
puts sigma(4, ^2, 20)

I will fiddle with your suggestions and continue with my sigma :slight_smile:

Thanks again for all your help


#6

On Jan 17, 2007, at 9:10 AM, Neutek wrote:

puts test(1, 2, “+”) #should return 3
puts test(3, 3, “^”) #should return 0
puts test(3, 3, “**”) #should return 27

any help would be appreciated.

You’re very close:

def test(a, b, to_do)
a.send(to_do, b)
end
=> nil

test(1, 2, “+”)
=> 3

test(3, 3, ‘^’)
=> 0

test(3, 3, ‘**’)
=> 27

Rob B. http://agileconsultingllc.com
removed_email_address@domain.invalid
Skype: rob.biedenharn


#7

Robert K.:

irb(main):003:0> def test(a,b,op) a.send(op.to_sym,b) end
^^^^^^
=> nil
irb(main):004:0> test 1,2,"+"
=> 3

Any specific reason for to_sym’s appearing there?

Kalman


#8

** SPOILER **

Don’t read on if you first want to experiment yourself.

On 17.01.2007 17:48, Neutek wrote:

Robert, I was actually reading the summation wiki and they had a few
code examples in C++/Java… I thought I’d goof a bit and write
something out in ruby. Of course, I hit the roadblock when trying to
pass math operators(or methods rather) to a method…

What is the “summation wiki”? Are you referring to this page?
http://en.wikipedia.org/wiki/Sum

If yes, here are some more ways:

plain values

sum = (m…n).inject(0){|s,x| s + x}

with a function

f = lambda {|i| i * 2}
sum = (m…n).inject(0){|s,x| s + f[x]}

in a method

def sum(m, n, f)
(m…n).inject(0){|s,x| s + f[x]}
end

s = sum( 1, 2, lambda {|x| x * 2} )

etc.

Advantage of using lambdas is that they are more flexible than method
names and can contain arbitrary calculations.

Kind regards

robert

PS: Please don’t top post.


#9

Robert K. wrote:

sum = (m…n).inject(0){|s,x| s + f[x]}
Advantage of using lambdas is that they are more flexible than method
names and can contain arbitrary calculations.

Kind regards

robert

PS: Please don’t top post.

What’s top post? (sorry, I’m new to google groups --I put my reply at
the bottom if this is what you meant )

I’ll read through your example now but figured what I worked on in the
interim was worth posting…

#works
def test(a, to_do, b)
return a.send(to_do, b)
end
puts test(2, :**, 3)

#does not work when trying to send an entire mathematical expresion as
a param
def sigma(floor, to_do, cap)
x = 0
floor.upto(cap) {|i|
x += i.send(to_do)
}
return x
end
puts sigma(4, :**2, 20)

#does not work… but another example of what I would expect :frowning:

def do_it(n, to_do)
return n.send(to_do)
end
puts sigma(3, :+4/2) #should yield 5

(Thank you)²


#10

On 17.01.2007 17:47, Kalman N. wrote:

Robert K.:

irb(main):003:0> def test(a,b,op) a.send(op.to_sym,b) end
^^^^^^
=> nil
irb(main):004:0> test 1,2,"+"
=> 3

Any specific reason for to_sym’s appearing there?

Yes, my ignorance. :slight_smile:

robert


#11

On 17.01.2007 18:21, Neutek wrote:

}
return x
end
puts sigma(4, lambda{|x| x ** 2}, 20)

Thanks a million!

Basically if you think this further through, what you are trying to do
is already part of Ruby’s standard lib. The method is #inject. I think
I used it in one of my postings. Your piece above becomes

puts (4…20).inject(0) {|s,x| s + x ** 2}

or, to more directly translate using #upto

require ‘enumerator’
puts 4.to_enum(:upto, 20).inject(0) {|s,x| s + x ** 2}

Cheers

robert


#12

Cool… I think this works :slight_smile:

#does not work when trying to send an entire mathematical expresion as
a param
def sigma(floor, to_do, cap)
x = 0
floor.upto(cap) {|i|
#x += i.send(to_do)
x += to_do[i]
}
return x
end
puts sigma(4, lambda{|x| x ** 2}, 20)

Thanks a million!