Yesterday, I read a blog about lazy function definition pattern in
JavaScript at http://peter.michaux.ca/article/3556 .
It was interesting and insightful.
Write a function foo that returns a Date object that holds the time
that foo was first called.
var foo = function() {
var t = new Date();
foo = function() {
return t;
};
return foo();
};
In ruby, one would write the following way or something like that if
he wants to cache the first value.
def foo @t or (@t = Time.new)
end
But the writer wants to remove the conditional part because it’s run
every time the function is called.
JavaScript allows functions to be redefined very easily.
I think ruby allows it but not very easily.
I came up with this idea.
class Lazy
def method_missing *args
if args[0] == :foo @t = Time.new
class << self
def foo @t
end
end
return foo
end
end
end
But I believe that ruby gurus will have better ideas.
What would be the lazy function definition pattern in ruby?
And do you think it’s useful?
Yesterday, I read a blog about lazy function definition pattern in
JavaScript at http://peter.michaux.ca/article/3556 .
It was interesting and insightful.
Write a function foo that returns a Date object that holds the time
that foo was first called.
var foo = function() {
var t = new Date();
foo = function() {
return t;
};
return foo();
};
In ruby, one would write the following way or something like that if
he wants to cache the first value.
def foo @t or (@t = Time.new)
end
But the writer wants to remove the conditional part because it’s run
every time the function is called.
JavaScript allows functions to be redefined very easily.
I think ruby allows it but not very easily.
I came up with this idea.
class Lazy
def method_missing *args
if args[0] == :foo @t = Time.new
class << self
def foo @t
end
end
return foo
end
end
end
But I believe that ruby gurus will have better ideas.
What would be the lazy function definition pattern in ruby?
And do you think it’s useful?
Thanks in advance.
Sam
You can define a method inside a method directly.
class Bar
def foo @t = Time.new
def foo @t
end @t
end
end
x=Bar.new
p x.foo # => Thu Aug 16 22:17:17 +0200 2007
sleep 5
p x.foo # => Thu Aug 16 22:17:17 +0200 2007
On Aug 16, 1:18 pm, “Wolfgang Nádasi-Donner” [email protected]
wrote:
he wants to cache the first value.
I came up with this idea.
return foo
Sam
end
end
x=Bar.new
p x.foo # => Thu Aug 16 22:17:17 +0200 2007
sleep 5
p x.foo # => Thu Aug 16 22:17:17 +0200 2007
Wolfgang Nádasi-Donner
Posted viahttp://www.ruby-forum.com/.
I didn’t know defining the same method in a method works.
It’s very similar to the one David suggested above.
But the syntax is easier and more intuitive.
It’s almost same as JavaScript’s pattern.
It’s good to know.^^
Bar.new.foo # Thu Aug 16 18:25:02 -0400 2007
Bar.new.foo # Thu Aug 16 18:25:03 -0400 2007
and each object keeps its own. Another possibility is:
class Bar
def foo
t = Time.now
self.class.class_eval do
define_method(:foo) { t }
end
t
end
end
That would preserve the time from the very first call to the method,
across all instances. It depends how one wants to fine-tune the
behavior, I guess.
As long as you don’t want to do the same thing in a subclass…
Everything is a tradeoff.
I’m not sure what the disadvantage of the local variable is, though.
It seems like a good fit, since all you need it for is the local
purpose of preserving it in the new definition.
David
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.