【问题标题】:Ruby: What is the meaning of "variable.property!" syntax?Ruby:“variable.property”是什么意思!句法?
【发布时间】:2020-04-27 14:29:03
【问题描述】:

我正在分析一段用 ruby​​ 编写的代码。 我不懂语言,我需要了解操作。

def restore
  m = ObjectName.where(prop: User.where(email: 'admin@email.com').first.element_id).last
  m.todo!
  m.waiting!
  ...
end

什么“m.todo!”和“m.waiting!”是做? 我无法理解它是否分配了“真实”值或与当前值相反的值,例如:m.todo = !m.todo

非常感谢

【问题讨论】:

    标签: ruby syntax variable-assignment operator-keyword


    【解决方案1】:

    !? 是 Ruby 中方法名称的有效部分。它们没有任何特殊含义,尽管! 通常用于突变或破坏性操作,而? 通常用于谓词方法。

    在此示例中,调用了两个名为 todo!waiting! 的方法 - 没有什么比这更好的了。如果我不得不猜测,这些方法只是执行组合的“更新状态变量并保存”操作(因此是可变的)。

    【讨论】:

    • 在 Rails 中 ! 也意味着“引发异常”,而非 ! 可能返回 nil
    • user2750691,“突变或破坏性动作”(如果不清楚)表示该方法更改其接收者的值,这里是变量m 持有的对象。例如,假设m = [1,2]。然后(没有'!'):m.map { |x| x+1 } #=> [2,3],之后是m #=> [1,2]。相比之下,m.map! { |x| x+1 } #=> [2,3],之后是m #=> [2,3]。方法名称末尾的感叹号告诉读者该方法做了一些可能“危险”的事情。对于核心方法(少数除外),这意味着它会改变它的接收器,这种做法通常被一些编码人员所反对。
    • @CarySwoveland: m.clear 也改变了它的接收器,但是并没有爆炸。规则是,爆炸标志着一对方​​法中的“更令人惊讶”。如果没有第二种方法,就没有爆炸。
    • @JörgWMittag,replace 方法家族是另一个例子,但我并没有说所有改变其接收者的方法都有一个爆炸(尽管你的观点是值得的)。我已经看到对“危险”和“令人惊讶”这两个形容词的引用,但我不知道它们都有任何官方地位。
    • 非常感谢。我会尝试更深入地研究代码,但是我在模型中找不到这些方法。似乎这些是来自 dto 的属性(布尔值)。
    【解决方案2】:

    在 Ruby 中,foo.bar消息发送 的语法。它将首先评估表达式 foo(它是取消引用局部变量或发送到隐式接收器 self 的无接收器消息),然后将消息 bar 发送到结果对象。

    一旦你知道 Ruby 中发送的消息是什么样的,就很容易看出 m.todo! 做了什么:它将首先评估表达式 m(它要么取消引用局部变量,要么将无接收消息发送到隐式接收者self),然后将消息todo!发送到生成的对象。

    ! 结尾的方法名称通常用于标记一对方法中“更令人惊讶”的地方。所以,如果你有 两个 方法,它们都做类似的事情,那么最后带有 bang 的那个是“更令人惊讶”的那个。一个很好的例子是Process::exitProcess::exit!。两者都退出当前运行的 Ruby 进程,但“正常”版本(即没有 bang)正常运行退出处理程序,而“令人惊讶”版本立即退出运行退出处理程序。

    注意:关于 bang 方法的命名约定似乎有很多误解。所以,让我说清楚:

    1. Bang 方法与突变或破坏完全无关。这只是关于惊喜。请参阅上面的 Process::exit! 示例,它与突变无关。
    2. Bang 方法总是与非 bang 方法配对使用。它们标志着一对方​​法的“更令人惊讶”的变体。如果没有成对的方法,就没有爆炸。例如,参见Array#collect!,它确实有一个爆炸,因为它是Array#collect 的更令人惊讶的变体,因为它改变了它的接收器;然而,Array#append 确实没有有爆炸性,即使它也改变了它的接收器,因为没有相应的“不那么令人惊讶”的方法。

    什么“m.todo!”和“m.waiting!”是做?我无法理解它是否分配了“真实”值或与当前值相反的值,例如:m.todo = !m.todo

    他们做这些方法的作者想要的任何事情。您必须在文档中查找。这些不是 Ruby 核心或标准库的方法。

    【讨论】:

    • 我问的不是方法本身的行为,而是 if 的含义!和 ? .我知道我不能问你他们是做什么的:)
    猜你喜欢
    • 1970-01-01
    • 2016-08-17
    • 2011-04-18
    • 2016-09-17
    • 2011-10-14
    • 2021-11-10
    • 2014-06-21
    • 2011-01-11
    • 2011-11-18
    相关资源
    最近更新 更多