定义? Ruby 和 Rails 中的方法

Posted

技术标签:

【中文标题】定义? Ruby 和 Rails 中的方法【英文标题】:defined? method in Ruby and Rails 【发布时间】:2010-09-19 07:29:04 【问题描述】:

我有一个非常古老的模板系统,它是在 ERB 之上编写的。它依赖于存储在数据库中的 ERB 模板。那些被读取和渲染。当我想将数据从一个模板传递到另一个模板时,我使用 Rails 渲染方法的 :locals 参数。为了在某​​些模板中设置这些变量的默认变量,我使用定义的?方法,它只是告诉我是否已定义局部变量,如果没有,我将其初始化为默认值,如下所示:

unless defined?(perex)
  perex = true
end

我正在将应用程序升级到最新的 Rails,我看到一些奇怪的行为。基本上,这有时有效(有时 perex 未定义),有时则无效(perex 已定义并设置为 nil)。在没有任何其他改变的情况下发生这种情况。

我有两个问题: 除了使用定义之外,还有什么更好的方法吗?哪个被证明是不可靠的(在 Rails 1.6 上几年可靠)?这种方式不应该导致我重写所有模板。 我一直在浏览 Ruby 文档,但找不到任何关于定义的内容?方法。它被弃用了还是我只是瞎了眼?

编辑: 实际问题是由似乎是 Ruby/eRB 错误引起的。有时 unless 语句会起作用,但有时不会。奇怪的是,即使第二行被执行 perex 仍然对世界其他地方保持零。删除定义?解决了。​​

【问题讨论】:

【参考方案1】:

首先:实际上,defined? is an operator。

第二:如果我正确理解了你的问题,那么用这个 Ruby 习语就可以了:

perex ||= true

如果 perex 未定义或 nil,则将其赋值为 true。这不完全是您的示例所做的,因为当值为nil 时,您的示例不会评估分配,但是如果您依赖它,那么在我看来,如果没有看到它,您就没有编写清晰的代码。

编辑:正如 Honza 所说,上面的语句将替换 perex 的值,当它是 false 时。然后我提出以下重写最小行数:

perex ||= perex.nil?  # Assign true only when perex is undefined or nil

【讨论】:

这不是真的。 perex ||= true 与 perex = perex || 相同true 如果 perex 未定义、nil 或 false,则将其设置为 true。最后一种情况会破坏一切。【参考方案2】:

如果在 Rails 模板中定义了本地,最安全的测试方法是:

local_assigns[:perex]

Rails API 中记录了这一点,并说明了 defined? 由于实现限制而无法使用。

【讨论】:

如果perex的值为false怎么办? 你可以自己检查:) perex = true if local_assigns[:perex].nil?【参考方案3】:

根据 mislav 的回答,我在 Rails API 中查找该文档,并在 Class ActionView::Base 中找到它(在“将局部变量传递给子模板”标题下)。然而,这几乎不值得搜索,因为它几乎没有比米斯拉夫多说什么。除了它推荐这种模式:

if local_assigns.has_key? :perex

【讨论】:

现在不推荐使用 Hash#key?但我认为现在仍然有效。【参考方案4】:

考虑到mislav's original answer 和KenB's elaboration,我认为以下是绝对最好的方法(尽管我持开放态度)。如果原始哈希中不存在键,它会利用 Ruby 的 Hash#fetch 方法回退到备用值。

perex = local_assigns.fetch(:perex, true)

这甚至比大多数用户建议的||= 方法更好,因为有时您会希望允许false 值。例如,以下代码将从不允许传入 false 值:

perex = local_assigns[:perex] || true

【讨论】:

以上是关于定义? Ruby 和 Rails 中的方法的主要内容,如果未能解决你的问题,请参考以下文章

升级到 ruby​​ 3 和 rails 6.1 后未定义的方法“file_fixture_path”

尝试使用to_json生成嵌套的json格式时,ruby on rails中的未定义方法错误?

Ruby on Rails 学习五Ruby语言的方法

Ruby on Rails:未定义的方法 'digest' Rails 教程第 10.1.1 节

Ruby on Rails:高级搜索,nil:Nilclass 的未定义方法 []

Ruby on Rails - 从视图调用控制器方法