[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

define a function inside a method

Olivier

3/3/2007 2:41:00 PM

Hi,

I wrote a method which uses recursion, internally. As a test, I tried to
define the recursive function inside the method that is called :

class Ga
def bu
def zo(n)
# recursively call zo
end
10.times {|n| zo(n)}
end

At my surprise, this code ran well ! But I wonder if this is a good idea...
Should I be aware of possible problems, or limitations, coming from this
kind of construction ? I can't figure out where the zo function
actually "lives".

Thanks.

--
Olivier Renaud

4 Answers

Robert Klemme

3/3/2007 3:05:00 PM

0

On 03.03.2007 15:41, Olivier Renaud wrote:
> Hi,
>
> I wrote a method which uses recursion, internally. As a test, I tried to
> define the recursive function inside the method that is called :
>
> class Ga
> def bu
> def zo(n)
> # recursively call zo
> end
> 10.times {|n| zo(n)}
> end
>
> At my surprise, this code ran well ! But I wonder if this is a good idea...
> Should I be aware of possible problems, or limitations, coming from this
> kind of construction ? I can't figure out where the zo function
> actually "lives".

The issue here is (apart from the missing "end" in your piece above)
that zo will be defined every time you execute bu - that's probably not
something you want as it is inefficient and you do not actually change
zu's definition. Also, zo becomes a normal method - there is no such
thing as a nested method in Ruby:

irb(main):001:0> class Ga
irb(main):002:1> def bu
irb(main):003:2> def zo(n)
irb(main):004:3> # recursively call zo
irb(main):005:3* end
irb(main):006:2> 10.times {|n| zo(n)}
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> Ga.new.zo 1
NoMethodError: undefined method `zo' for #<Ga:0x39ba98>
from (irb):9
from :0
irb(main):010:0> Ga.new.bu
=> 10
irb(main):011:0> Ga.new.zo 1
=> nil

Kind regards

robert

Olivier

3/3/2007 3:26:00 PM

0

Le samedi 03 mars 2007 16:10, Robert Klemme a écrit :
> On 03.03.2007 15:41, Olivier Renaud wrote:
> > Hi,
> >
> > I wrote a method which uses recursion, internally. As a test, I tried to
> > define the recursive function inside the method that is called :
> >
> > class Ga
> > def bu
> > def zo(n)
> > # recursively call zo
> > end
> > 10.times {|n| zo(n)}
> > end
> >
> > At my surprise, this code ran well ! But I wonder if this is a good
> > idea... Should I be aware of possible problems, or limitations, coming
> > from this kind of construction ? I can't figure out where the zo function
> > actually "lives".
>
> The issue here is (apart from the missing "end" in your piece above)
> that zo will be defined every time you execute bu - that's probably not
> something you want as it is inefficient and you do not actually change
> zu's definition. Also, zo becomes a normal method - there is no such
> thing as a nested method in Ruby:
>
> irb(main):001:0> class Ga
> irb(main):002:1> def bu
> irb(main):003:2> def zo(n)
> irb(main):004:3> # recursively call zo
> irb(main):005:3* end
> irb(main):006:2> 10.times {|n| zo(n)}
> irb(main):007:2> end
> irb(main):008:1> end
> => nil
> irb(main):009:0> Ga.new.zo 1
> NoMethodError: undefined method `zo' for #<Ga:0x39ba98>
> from (irb):9
> from :0
> irb(main):010:0> Ga.new.bu
> => 10
> irb(main):011:0> Ga.new.zo 1
> => nil
>
> Kind regards
>
> robert

Thanks, this is perfectly clear !
Finally, I rewrote this method to avoid the recursion, since it was a tail
recursion.

--
Olivier Renaud

Gavin Kistner

3/3/2007 3:30:00 PM

0

On Mar 3, 7:41 am, Olivier Renaud <o.ren...@laposte.net> wrote:
> I wrote a method which uses recursion, internally. As a test, I tried to
> define the recursive function inside the method that is called :

Time to investigate:

class Foo
def bar
p jim rescue p "no jim yet"
def jim; "jim"; end
jim
end
end

f1 = Foo.new

p f1.jim rescue p "no jim yet"
#=> "no jim yet"

p f1.bar
#=> "no jim yet"
#=> "jim"

p f1.jim
#=> "jim"

f2 = Foo.new
p f2.jim
#=> "jim"

p f1.method( :jim )
#=> #<Method: Foo#jim>


What I deduce from this is that running Foo#bar causes a new instance
method "jim" to be defined for the Foo class. The only thing this gets
you is delayed method realization, once only, per class. It's not a
private function for the use by that method only.

Pit Capitain

3/3/2007 5:12:00 PM

0

Olivier Renaud schrieb:
> I wrote a method which uses recursion, internally. As a test, I tried to
> define the recursive function inside the method that is called :
>
> class Ga
> def bu
> def zo(n)
> # recursively call zo
> end
> 10.times {|n| zo(n)}
> end

In addition to the other answers, if you really want method-internal
methods, you can use lambdas:

class Ga
def bu
zo = lambda {|n|
# recursively call zo
}
10.times {|n| zo.call(n)}
end
end

Regards,
Pit