0

在开发自己的库的过程中,我一直在阅读 Github 上的各种 Ruby 库,以了解常见的习语。我一直在引用的一个库(在此处找到)利用了我所谓的“未附加发送方法”。这是代码:

module AngellistApi
    class API

        attr_accessor *Configuration::VALID_OPTIONS_KEYS

        # Creates a new API
        def initialize(options={})
          options = AngellistApi.options.merge(options)
          Configuration::VALID_OPTIONS_KEYS.each do |key|
            send("#{key}=", options[key])
          end 
        end
    end  
end 

我可以在网上找到有关 Ruby 中的 send 方法的所有文档,都将其描述为一种通过字符串或符号调用对象方法的方式。但是,所有示例都将 send 方法附加到对象,例如:

object.send(:method_name, argument1)

当它没有连接到一个对象时会发生什么?在这种情况下,它是在调用它所调用的类的方法吗?有人可以为我解释这段代码吗?:)

4

3 回答 3

2

“未附加”不是正确的术语,它是一个没有显式接收器的方法调用,因此它使用隐式接收器,即self. 所以send(:foo)(隐式接收器)等价于self.send(:foo)(显式接收器)。这不是唯一的send,任何方法调用都是如此。

唯一不完全正确的情况是被调用的方法是私有的,因为私有方法不能用显式接收者调用(实际上,这是 Ruby 中私有的定义)。

于 2012-11-24T21:16:23.390 回答
1

由于它发生在实例方法中,这里的隐含对象是self.

# create a new object, assigning "foo = bar" given that
# foo is in VALID_OPTIONS_KEYS
object = AngellistApi::API.new({:foo => 'bar'})

# this would essentially do the same thing again
object.send("foo=", "bar")

# (which is equivalent to)
object.foo = bar
于 2012-11-24T21:07:11.163 回答
0

Generally speaking, in Ruby when a method is called without an explicit receiver, the implicit receiver is self. self can sometimes be slippery though -- understanding what self is in various contexts is an important and enlightening step in the path to Ruby mastery :-) Yehuda Katz has a nice article on the subject, and there are many others out there.

I think the Pry alternative REPL can be helpful for exploring. A sample session where the AngelList API lib was loaded:

[1] pry(main)> cd AngellistApi::API
[2] pry(AngellistApi::API):2> self
=> AngellistApi::API
[3] pry(AngellistApi::API):2> ls
Object.methods: yaml_tag
AngellistApi::API#methods: access_token  access_token=  adapter  adapter=  connection_options  connection_options=  endpoint  endpoint=  gateway  gateway=  proxy  proxy=  user_agent  user_agent=
locals: _  _dir_  _ex_  _file_  _in_  _out_  _pry_  binding_impl_method

Here you can see the accessors that were defined as a result of attr_accessor *Configuration::VALID_OPTIONS_KEYS.

于 2012-11-24T21:23:07.100 回答