Passing math method to another method?

Discussion in 'Ruby' started by Neutek, Jan 17, 2007.

  1. Neutek

    Neutek Guest

    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.
     
    Neutek, Jan 17, 2007
    #1
    1. Advertising

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

    > 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.


    >> 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 Gray II
     
    James Edward Gray II, Jan 17, 2007
    #2
    1. Advertising

  3. Neutek

    Xavier Noria Guest

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

    > 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


    a.send(to_do, b)
     
    Xavier Noria, Jan 17, 2007
    #3
  4. On Jan 17, 2007, at 9:10 AM, Neutek wrote:

    > 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.


    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 Biedenharn http://agileconsultingllc.com

    Skype: rob.biedenharn
     
    Rob Biedenharn, Jan 17, 2007
    #4
  5. On 17.01.2007 15:06, Neutek wrote:
    > 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.


    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
     
    Robert Klemme, Jan 17, 2007
    #5
  6. Neutek

    Kalman Noel Guest

    Robert Klemme:
    > 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
     
    Kalman Noel, Jan 17, 2007
    #6
  7. Neutek

    Neutek Guest

    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 ;-)

    def sigma(floor, to_do, cap)

    end
    puts sigma(4, ^2, 20)

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

    Thanks again for all your help


    Robert Klemme wrote:
    > On 17.01.2007 15:06, Neutek wrote:
    > > 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.

    >
    > 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
     
    Neutek, Jan 17, 2007
    #7
  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.
     
    Robert Klemme, Jan 17, 2007
    #8
  9. On 17.01.2007 17:47, Kalman Noel wrote:
    > Robert Klemme:
    >> 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. :)

    robert
     
    Robert Klemme, Jan 17, 2007
    #9
  10. Neutek

    Neutek Guest

    Robert Klemme wrote:
    > ** 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.


    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 :(

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


    (Thank you)²
     
    Neutek, Jan 17, 2007
    #10
  11. Neutek

    Neutek Guest

    Cool... I think this works :)


    #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
    }
    return x
    end
    puts sigma(4, lambda{|x| x ** 2}, 20)

    Thanks a million!


    Neutek wrote:
    > Robert Klemme wrote:
    > > ** 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.

    >
    > 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 :(
    >
    > def do_it(n, to_do)
    > return n.send(to_do)
    > end
    > puts sigma(3, :+4/2) #should yield 5
    >
    >
    > (Thank you)²
     
    Neutek, Jan 17, 2007
    #11
  12. On 17.01.2007 18:21, Neutek wrote:
    > Cool... I think this works :)
    >
    >
    > #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
    > }
    > 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
     
    Robert Klemme, Jan 18, 2007
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. chirs
    Replies:
    18
    Views:
    790
    Chris Uppal
    Mar 2, 2004
  2. AciD_X
    Replies:
    4
    Views:
    8,144
    Jonathan Turkanis
    Apr 1, 2004
  3. Mark Healey
    Replies:
    7
    Views:
    1,528
    Tim Prince
    May 22, 2006
  4. Philipp
    Replies:
    9
    Views:
    1,154
    Mark Space
    Jul 23, 2008
  5. VK
    Replies:
    15
    Views:
    1,236
    Dr J R Stockton
    May 2, 2010
Loading...

Share This Page