【问题标题】:Error: Attempt to call private method错误:尝试调用私有方法
【发布时间】:2010-11-21 00:48:27
【问题描述】:

来自 C 样式语法的悠久历史,现在正在尝试学习 Ruby(在 Rails 上),我一直在其习语等方面遇到问题,但今天我遇到了一个我没想到的问题有问题,我看不到必须在我面前的任何东西。

我有一个 Binary 类,它包含一个从路径值派生 URI 值的私有方法(uri 和路径是类的属性)。我从Binary.upload() 内部调用self.get_uri_from_path(),但我得到:

Attempt to call private method

模型的 sn-p 如下所示:

class Binary < ActiveRecord::Base
  has_one :image

  def upload( uploaded_file, save = false )
    save_as = File.join( self.get_bin_root(), '_tmp', uploaded_file.original_path )

    # write the file to a temporary directory
    # set a few object properties

    self.path   = save_as.sub( Rails.root.to_s + '/', '' )
    self.uri    = self.get_uri_from_path()
  end

  private

  def get_uri_from_path
    return self.path.sub( 'public', '' )
  end
end

我是不是打错电话了?我是否错过了其他更基本的东西?唯一调用Binary.get_uri_from_path() 的地方——目前——是Binary.upload()。我希望能够在同一个类中调用私有方法,除非 Ruby 所做的事情与我使用的其他语言明显不同。

谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby access-specifier private-methods


    【解决方案1】:

    别这样

    self.get_uri_from_path()
    

    get_uri_from_path()
    

    因为……

      class AccessPrivate
        def a
        end
        private :a # a is private method
    
        def accessing_private
          a              # sure! 
          self.a         # nope! private methods cannot be called with an explicit receiver at all, even if that receiver is "self"
          other_object.a # nope, a is private, you can't get it (but if it was protected, you could!)
        end
      end
    

    via

    【讨论】:

    • 谢谢。更多的挖掘帮助我理解了 Ruby 与其他语言的私有方法的区别。我只是没想到会在那个级别出现差异。
    • 不客气。的确,这有点棘手,但一段时间后它实际上是有道理的:)
    • 我发现很多 Ruby 都很棒 - 简洁,但富有表现力 - 但我肯定要克服成语增量。 :-)
    【解决方案2】:

    我相信在这种情况下正确的习语不是 self.get_uri_from_path() 而是简单的 get_uri_from_path()。自我是多余的。进一步说明: * self.path调用self上的path方法,想必是在父类中定义的。如果你想直接访问实例变量,你可以说@path。 (@ 是实例变量的标志。) * 方法参数的括号是可选的,除非它们的缺失会导致歧义。如果您愿意,您可以将 get_uri_from_path() 替换为 get_uri_from_path。这与 Javascript 形成鲜明对比,在 Javascript 中,没有括号的函数将该函数表示为一个值,而不是该函数的应用程序。

    【讨论】:

    • 是的,我知道可选的括号,但我一直看到没有它们的东西,我不喜欢模棱两可。它是变量还是方法?我宁愿不必每次看到它时都问自己这个问题。也许随着时间的推移会变得更容易。
    【解决方案3】:

    在任何情况下你都可以调用私有方法,那就是:

    object.send(:private_method)
    

    我相信 1.9 对这个技巧有不同的实现

    【讨论】:

    • 是的,1.9有发送!方法。
    • 此时,我只是在努力学习和理解规则。以后我会担心“破坏”它们。 :-)
    • 1.9.2 没有send! 方法。它确实有send
    猜你喜欢
    • 2018-10-23
    • 2019-01-06
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多