Stripe API开放了元类?或者只是定义一个类方法?

时间:2016-10-06 23:11:09

标签: ruby

我正在阅读Stripe API,我看到了:

module Stripe

  ...

  class << self
    attr_accessor :stripe_account, :api_key, :api_base, :verify_ssl_certs, :api_version, :connect_base, :uploads_base,
                  :open_timeout, :read_timeout

    attr_reader :max_network_retry_delay, :initial_network_retry_delay
  end

那里发生了什么?我尝试过阅读Yehuda Katz的博客,但部分内容有点不清楚,如下:

他提供的两个例子中发生了什么?

  

事实证明,所有这些奇怪的规则都会崩溃成单一的   概念:在代码的给定部分中控制自我。我们走吧   回过头来看看我们之前看过的一些片段:

class Person     
   def name
      "Matz" 
   end

  self.name #=> "Person" 
end   
  

在这里,我们将添加名称方法   Person类。一旦我们说class Person,自我直到结束   该块本身就是Person类。

Person.class_eval do     
   def name
       "Matz"
   end

   self.name #=> "Person"
end 
  

在这里,我们做的完全一样   thing:将name方法添加到Person类的实例中。在   在这种情况下,class_eval将自我设置为Person直到结束   块。在处理时,这一切都非常简单   课程,但在处理时同样直截了当   元类:

为什么耶胡达继续写作:

self.name #=> "Person"

1 个答案:

答案 0 :(得分:2)

Ruby中没有“类方法”这样的东西。所有方法都是实例方法。事情只是实例不同。

Stripe是类Module的实例,Person是类Class的实例。

因此,在您的第一个示例(Stripe)中,对象attr_accessor可以使用Stripe的定义。

因此,您将能够读取和写入Stripe的属性:

Stripe.api_key = :some_key
Stripe.api_key
#=> :some_key

虽然以下定义了可用于类Person

的实例的方法
Person.class_eval do
  def name
    "Matz"
  end
end

您可以使用instance_evalPerson类定义实例方法,该方法在接收器的上下文中评估代码:

Person.instance_eval do
  def name
    "Matz"
  end
end
Person.name # this is what they sometimes called  "a class method", which I don't like personally
#=> 'Matz'

这始终只是一个背景问题。一旦你理解了self是什么以及self随时指向的地方 - 事情会变得更加清晰。