我有时会使用这个结构:
class Test
def today
date = Date.today
def date.is_friday?
strftime("%A") == "Friday"
end
date
end
end它工作得很好。
t = Test.new
t.today # => <Date: 2016-09-03 ((2457635j,0s,0n),+0s,2299161j)>
t.today.is_friday? # => false我一直认为这是一个嵌套的方法。但是其他人坚持认为Ruby没有嵌套的方法。好吧,我不是被名字迷住了。但是你怎么称呼它呢?有没有更好的方法来实现同样的功能?
发布于 2016-09-04 13:54:36
当人们谈论嵌套方法/函数时,他们通常指的是仅在封闭方法中可见/可用的东西。但您的示例并非如此-一旦定义,任何人都可以在该对象上调用它。
您展示的是ruby的单例方法:在类的一个实例上定义方法的能力(例如,当人们说ruby中的类方法时,这些方法实际上是Class类实例上的单例方法)。
至于是否有更好的方法,这是无法回答的,因为你还没有说你试图解决的问题是什么。
发布于 2016-09-04 13:58:13
在方法中调用def通常是错误的方式。您需要的是定义一个封装此方法和其他方法的模块,然后根据需要将其混合到任何对象中:
module DateExtensions
def is_friday?
wday == 5
end
end值得注意的是,strftime可能会返回“星期五”以外的值,因为本地化可能会生效。根据你所在的位置,你可以得到"Freitag“或"Vendredi”。wday方法返回一个可预测的数值。
现在,您可以将以下代码混合在一起:
class Test
def today
date = Date.today
date.extend(DateExtensions)
date
end
end通过在模块中声明这些方法,很明显它们是包的一部分。这也意味着你不需要为你创建的每个Date实例定义一个全新的方法。
一种更Ruby的方式是定义你自己的Date子类,它添加了这个额外的行为。
发布于 2016-09-05 01:40:44
方法定义是代码,就像其他代码一样。它们可以像任何其他代码一样出现在方法中。就像任何其他代码一样,它们将在每次方法运行时执行。
所以,这个
class Foo
def foo
def bar
end
end
end不是嵌套方法,而仅仅是定义方法的方法。很容易看出,这不是一个嵌套的方法,只需调用它两次,注意生成的警告并检查周围模块的已定义方法:
foo = Foo.new
Foo.public_instance_methods(false)
#=> [:foo]
foo.foo
Foo.public_instance_methods(false)
#=> [:foo, :bar]
foo.foo
# (irb):3: warning: method redefined; discarding old bar
# (irb):3: warning: previous definition of bar was here正如您所看到的,bar并没有嵌套在foo中,而是在Foo类中的foo之外定义的。它只在foo运行后定义,并且每次foo运行时都会重新定义。
当然,您的示例有点不同,因为它不会一直覆盖同一个类中的方法,而是在每次调用时都在不同的类中定义它。
请注意,有禁止这种使用的计划,请参阅Feature #11665: 。
,但是你怎么称呼它呢?
它是一种定义方法的方法。
,有没有更好的方法来实现同样的功能?
很难说清楚你到底想要实现什么。
您可以使用您的方法创建一个module,并使用它extend所有对象。这将是最接近的类比。
其他解决方案需要对代码进行更大规模的重构,例如使用Decorator Design Pattern,或者在您的特定Rails用例中使用Presenter。
https://stackoverflow.com/questions/39313535
复制相似问题