2009-08-19 4 views
22

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

Спасибо.

ответ

43

Не делайте

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

+1

Спасибо. Немного больше копания помогли мне понять различия в частных методах Ruby и других языках. Я просто не ожидал различий на этом уровне. –

+0

добро пожаловать. Это правда, это немного сложнее, но на самом деле это имеет смысл через некоторое время :) – marcgg

+0

Я нахожу, что много Ruby потрясающее - лаконичное, но выразительное - но я определенно должен сражаться в дельтах идиомы. :-) –

1

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

+0

Да, я знаю о дополнительных парадах, но я продолжаю видеть вещи без них, и мне не нравится двусмысленность. Это переменная или это метод? Я бы не стал задавать себе этот вопрос каждый раз, когда я это вижу. Может быть, со временем это станет легче. –

1

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

object.send(:private_method) 

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

+0

Да, 1.9 имеет отправку! метод. –

+0

На данный момент я просто пытаюсь изучить и понять правила. Я буду беспокоиться о том, чтобы «сломать» их позже. :-) –

+0

1.9.2 не имеет 'send!'метод. У него действительно есть «отправить». – Dex

Смежные вопросы