Ошибка: попытка вызвать закрытый метод - PullRequest
23 голосов
/ 19 августа 2009

Исходя из долгой истории синтаксиса в стиле C и теперь пытаясь изучать Ruby (на Rails), у меня была своя доля проблем с его идиомами и тому подобным, но сегодня я столкнулся с тем, чего не ожидал у меня есть проблема, и я не могу видеть, что это должно быть прямо перед моим лицом.

У меня есть двоичный класс, который включает частный метод для получения значения URI из значения пути (uri и path являются атрибутами класса). Я звоню self.get_uri_from_path() изнутри Binary.upload(), но получаю:

Attempt to call private method

Фрагмент модели выглядит следующим образом:

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 не делает что-то заметно отличающееся от других языков, которые я использовал.

Спасибо.

Ответы [ 3 ]

46 голосов
/ 19 августа 2009

Не делай

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

через

1 голос
/ 20 августа 2009

есть черт, хотя вы можете вызывать приватный метод в любой ситуации, например:

object.send(:private_method)

Я считаю, что 1.9 имеет другую реализацию этого трюка

1 голос
/ 19 августа 2009

Я считаю, что правильной идиомой в этом случае является не self.get_uri_from_path (), а скорее просто get_uri_from_path (). Самость избыточна. Дальнейшие заметки: * self.path вызывает метод path для self, который предположительно определен в родительском классе. Если бы вы хотели получить доступ к переменной экземпляра напрямую, вы могли бы сказать @path. (@ является символом переменных экземпляра.) * Скобки для аргументов метода являются необязательными, за исключением случаев, когда их отсутствие может привести к неоднозначности. Если хотите, вы можете заменить get_uri_from_path () на get_uri_from_path. Это отличается от Javascript, где функция без символов представляет эту функцию как значение, а не приложение этой функции.

...