我是一个 Ruby 的新手。
在一个 Ruby on Rails 项目中,我在 models 文件夹下的一个 rb 文件中发现了以下代码:
...
before_validation :start_at, if: -> { status_change? && finished? }
...
我不理解这里使用的语法...你能告诉我这里的
if:
和->
是什么意思吗?谢谢。
我是一个 Ruby 的新手。
在一个 Ruby on Rails 项目中,我在 models 文件夹下的一个 rb 文件中发现了以下代码:
...
before_validation :start_at, if: -> { status_change? && finished? }
...
if:
和->
是什么意思吗?哇,你的问题涉及很多内容...
Ruby允许你在一行代码的结尾放置单行if
语句。如果if
语句返回true,则执行前面的语句。这些通常用于"守卫条件"。但这不完全是这里正在发生的事情...
Ruby还允许你省略方法调用周围的括号,如果它可以推断出确切的参数。例如,你可以输入sum a, b
而不是sum(a, b)
。这是使Ruby适合编写像Rake和ActiveRecord的"特定领域语言"之一。Thoughtbot有一篇好文章介绍了这方面的内容。
因此,该行代码可以重写为:
before_validation(:start_at, if: -> { status_change? && finished? })
在这种情况下,before_validation
是一个 ActiveRecord 回调函数。根据文中链接的内容,“回调函数是在对象生命周期的某些时刻被调用的方法。使用回调函数可以编写代码,在 Active Record 对象创建、保存、更新、删除、验证或从数据库加载时运行。”
在这个例子中,你看到的是一个“条件回调函数”。start_at
方法(你可能会在模型文件底部找到该方法的定义,或者其他地方,在代码库中搜索“def start_at”)仅在条件通过时才会被调用。
关于条件本身,status_change?
和 finished?
也都是方法。问号表示这两个方法返回布尔值。而 &&
是布尔逻辑运算符,它表示只有当 status_change?
和 finished?
都返回 true 时,整个条件语句才会返回 true。
因此,简单来说,这行代码的作用是:
start_at
方法...status_change?
和 finished?
方法都返回 true 时在底层,这是通过将“lambda”作为参数传递给方法来实现的。在本例中,它使用了 Ruby 1.9 中引入的“stabby lambda”语法。请查看块、Procs 和 Lambdas 的终极指南和在 Ruby 中使用 Lambdas以获取更多信息。
before_validation
的 关键字参数。参数值是一个 proc 或 lambda。 - Stefanif:
表示符号:if
。如果您有一个哈希表,其中键是符号,则可以将其写为{:foo => 46, :bar => 16}
或更时髦的{foo: 46, bar: 16}
。->
表示lambda,即具有检查参数数量的Proc。如果有人调用它并错误地传递了参数,则会收到RuntimeError。 - user1934428def before_validation(*args, &block)
。 - engineersmnky