奇怪的Ruby语法

4

Action Mailer Basics Rails指南中,语法是什么?

class UserMailer < ActionMailer::Base
   def welcome_email(user)
      recipients    user.email
      from          "My Awesome Site Notifications <notifications@example.com>"
      subject       "Welcome to My Awesome Site"
      sent_on       Time.now
      body          {:user => user, :url => "http://example.com/login"}
   end
end

我应该如何理解构造,比如说

from "Some text for this field"

将值赋给一个变量,名为"from",这是一项任务吗?


1
请问您正在开发什么类型的应用程序?对于Rails开发人员来说,在ActionMailer上下文中遇到第一个无接收者消息发送是相当不寻常的。对于我所知道的大多数Rails开发人员来说,第一个无接收者消息发送是在ActiveRecord上下文中的has_manybelongs_to - Jörg W Mittag
4个回答

15

不是属性,而是方法调用。该方法的名称为from,参数为字符串。在Ruby中,方法调用周围的括号是可选的,因此

from "Some text for this field"

是相同的意思

from("Some text for this field")

Rails(以及许多Ruby库)喜欢用一种自然语言的风格来表达代码,因此省略括号的版本读起来更好,这就是为什么它在示例中使用的原因。


2
这是一个调用方法from并传入参数"Some text for this field"的语句。
该方法来自于你的UserMailer继承的ActionMailer::Base类。
在Ruby中,除非存在歧义,否则可以省略方法调用周围的圆括号,因此该语句相当于from("Some text for this field")。
Rails有一种编码风格,尽可能接近自然语言,因此除非必要,否则不使用括号。
调用此方法会将实例变量@from设置为您提供的值,以便稍后发送消息时使用。
通常情况下,如果您有访问器方法来获取和设置变量,则会使用from=来设置值,from来返回值,但是ActionMailer使用称为adv_attr_accessor的东西来定义from方法,因此如果您带参数调用它,则它充当setter,但如果您不带参数调用它,则充当getter。
这可以在actionmailer-2.x.x/lib/action_mailer/base.rb和actionmailer-2.x.x/lib/action_mailer/adv_attr_accessor.rb中看到。

1

这不是一个赋值操作。在 Ruby 中,使用赋值运算符=来进行赋值操作,如下:

var = val

你可能在想一些Lisp方言,其中赋值看起来像这样:

(def var val)

这只是一个简单的无接收方消息发送。

在Ruby中,消息发送的一般语法为

receiver.selector(argument1, argument2)

然而,如果receiverself,你可以省略receiver,因此

selector(argument1, argument2)

等同于

self.selector(argument1, argument2)

[注意:这并不完全正确。在 Ruby 中,私有方法只能通过无接收者的消息发送来调用,因此如果在此示例中 self 通过调用私有方法响应 selector 消息,则仅第一种变体将起作用,第二种将引发 NoMethodError 异常。]

此外,在没有歧义的情况下,您可以省略参数周围的括号,就像这样:

receiver.selector argument1, argument2

如果将这两个东西组合在一起,你现在可以看到

selector argument1, argument2

等同于

self.selector(argument1, argument2)

因此

from "Some text for this field"

等同于

self.from("Some text for this field")

在 Ruby 的消息发送语法中,有第三个快捷方式:如果消息发送的最后一个参数是一个 Hash 字面量,则可以省略花括号。因此,上面示例中的最后一行也可以写成:
  body          :user => user, :url => "http://example.com/login"

此外,在 Ruby 1.9 中,如果所有键都是符号(Symbol),则可以使用另一种哈希(Hash)字面量语法来编写哈希字面量。
 { key1: val1, key2: val2 }

与旧语法相同

{ :key1 => val1, :key2 => val2 }

这意味着,至少在 Ruby 1.9 中,最后一行也可以写成

  body          user: user, url: "http://example.com/login"

0
你也可以称from为属性。它是电子邮件的一个属性,但是它的实现对你来说是隐藏的(封装)。这是一个好事情。这意味着如果Rails核心决定将@from改为几个变量更好,那么你就不需要改动你的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接