我应该如何从ruby类中的静态方法调用对象方法?

时间:2017-07-10 10:46:28

标签: ruby

从学术/“为了利益”(最佳实践)的角度来看:

在Ruby类中,我想提供一个调用类的实例方法的静态方法。这被认为是一种可接受的方式吗,还是有“更好”的方式?

class MyUtil
    def apiClient
      @apiClient ||= begin
         apiClient = Vendor::API::Client.new("mykey")
      end
    end

    def self.setUpSomething(param1, param2, param3=nil)
      util = self.new() # <-- is this ok?
      util.apiClient.call("foo", param2)
      # some logic and more util.apiClient.calls() re-use client.
    end
end

然后我可以轻松使用这个lib:

MyUtil.setUpSomething("yes","blue")

vs

MyUtil.new().setupUpSomething()
# or
util = MyUtil.new()
util.setUpSomething()

环境是以受控方式执行的sys管理脚本,一次调用1次(即不是可能承受高负载的webapp类型的环境)。

3 个答案:

答案 0 :(得分:2)

在这种特殊情况下,您可能需要一个类实例变量:

class MyUtil
  @apiClient = Vendor::API::Client.new("mykey")

  def self.setUpSomething(param1, param2, param3=nil)
    @apiClient.call("foo", param2)
    # some logic and more util.apiClient.calls() re-use client.
  end
end

如果您想要延迟实例化,请使用访问者:

class MyUtil
  class << self
    def api_client
      @apiClient ||= Vendor::API::Client.new("mykey")
    end

    def setUpSomething(param1, param2, param3=nil)
      apiClient.call("foo", param2)
      # some logic and more util.apiClient.calls() re-use client.
    end
  end
end

答案 1 :(得分:2)

我个人可能会这样做:

 /* The Media */
@media screen and (max-width: 760px ) {
#contentsBox {
        width: 100%;
    }
#sideBarBox {
    width:100%;
}
#footer1 {
    width: 100%;
}
#footer2 {
    width: 100%;
}
#footer3 {
    width: 100%;
}
.postTitle {
    font-size: 105%;
}

#navMobileIcon{
    display: inline-block;
}
#navMenuBox #navMenu, #navMenuBox:active #navMenu{
    display: none;
    z-index: 1000;
    position: absolute;
    padding: 20px;
    background: #333;
    right: 20px;
    top: 80px;
    border: 2px solid #FFFFFF;
    border-radius: 10px 0 10px 10px;
    width: 50%;
}
#navMenuBox:hover #navMenu{
    display: block;
}
#navMenuItem {
    text-align: center;
    width: 100%;
    padding: 10px 0;
}
#navMenu a{
    font-size: 90%;
        color: #FFFFFF;
}
#logo {
    width: 100%;
}
#widgetTitle {
    font-size: 90%;
}
.footerWidgetTitle {
    font-size: 90%;
}
}

差别很小但是在这个版本中class MyUtil API_KEY = "mykey" def apiClient @apiClient end def initialize @apiClient = Vendor::API::Client.new(API_KEY) yield self if block_given? end class << self def setUpSomthing(arg1,arg2,arg3=nil) self.new do |util| #setup logic goes here end end def api_call(arg1,arg2,arg3) util = setUpSomthing(arg1,arg2,arg3) util.apiClient.call("foo", param2) #do other stuff end end end 保证了课程实例的返回,而且你所做的事情更加明显。

这里setUpSomthing负责设置对象,然后将其返回以便可以用于事物,这样就可以清楚地分离创建对象和设置对象。

答案 2 :(得分:0)

布雷特,你怎么看待这个:

class MyUtil
  API_KEY = 'SECRET'

  def do_something(data)
    api_client.foo(data)
  end

  def do_something_else(data)
    api_client.foo(data)
    api_client.bar(data)
  end

  private

  def api_client
    @api_client ||= Vendor::API::Client.new(API_KEY)
  end
end

用法

s = MyUtil.new
s.do_something('Example') # First call
s.do_something_else('Example 2')