首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Ruby没有嵌套的方法,对吧?那么这是什么,有没有更好的方法?

Ruby没有嵌套的方法,对吧?那么这是什么,有没有更好的方法?
EN

Stack Overflow用户
提问于 2016-09-04 12:26:06
回答 3查看 269关注 0票数 0

我有时会使用这个结构:

代码语言:javascript
运行
复制
class Test
  def today
    date = Date.today

    def date.is_friday?
      strftime("%A") == "Friday"
    end

    date
  end
end

它工作得很好。

代码语言:javascript
运行
复制
t = Test.new
t.today # => <Date: 2016-09-03 ((2457635j,0s,0n),+0s,2299161j)>
t.today.is_friday? # => false

我一直认为这是一个嵌套的方法。但是其他人坚持认为Ruby没有嵌套的方法。好吧,我不是被名字迷住了。但是你怎么称呼它呢?有没有更好的方法来实现同样的功能?

EN

回答 3

Stack Overflow用户

发布于 2016-09-04 13:54:36

当人们谈论嵌套方法/函数时,他们通常指的是仅在封闭方法中可见/可用的东西。但您的示例并非如此-一旦定义,任何人都可以在该对象上调用它。

您展示的是ruby的单例方法:在类的一个实例上定义方法的能力(例如,当人们说ruby中的类方法时,这些方法实际上是Class类实例上的单例方法)。

至于是否有更好的方法,这是无法回答的,因为你还没有说你试图解决的问题是什么。

票数 2
EN

Stack Overflow用户

发布于 2016-09-04 13:58:13

在方法中调用def通常是错误的方式。您需要的是定义一个封装此方法和其他方法的模块,然后根据需要将其混合到任何对象中:

代码语言:javascript
运行
复制
module DateExtensions
  def is_friday?
    wday == 5
  end
end

值得注意的是,strftime可能会返回“星期五”以外的值,因为本地化可能会生效。根据你所在的位置,你可以得到"Freitag“或"Vendredi”。wday方法返回一个可预测的数值。

现在,您可以将以下代码混合在一起:

代码语言:javascript
运行
复制
class Test
  def today
    date = Date.today

    date.extend(DateExtensions)

    date
  end
end

通过在模块中声明这些方法,很明显它们是包的一部分。这也意味着你不需要为你创建的每个Date实例定义一个全新的方法。

一种更Ruby的方式是定义你自己的Date子类,它添加了这个额外的行为。

票数 1
EN

Stack Overflow用户

发布于 2016-09-05 01:40:44

方法定义是代码,就像其他代码一样。它们可以像任何其他代码一样出现在方法中。就像任何其他代码一样,它们将在每次方法运行时执行。

所以,这个

代码语言:javascript
运行
复制
class Foo
  def foo
    def bar
    end
  end
end

不是嵌套方法,而仅仅是定义方法的方法。很容易看出,这不是一个嵌套的方法,只需调用它两次,注意生成的警告并检查周围模块的已定义方法:

代码语言:javascript
运行
复制
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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39313535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档