В структуре Spree Модель Product
определяет частный метод под названием build_variants_from_option_values_hash
.
Этот метод обычно вызывается изнутри функцией обратного вызова after_create
и объявляется внутри класса как private
. Я хотел бы использовать этот метод вне обычного жизненного цикла create и вызывать его напрямую, однако, поскольку он объявлен частным образом, к сожалению, он не виден за пределами класса.
Вопрос: Есть ли способ изменить видимость метода без его переопределения?
Используя class_eval
, я могу переопределить метод в декораторе продукта за пределами области private
, и это действительно помогает. Однако мне кажется, что полное копирование всего метода просто для того, чтобы изменить его видимость, является ненужным подходом типа «обезьяньего исправления». Есть ли лучший способ добиться этого?
2 ответа
Хотя подход @ МалъСкрылевъ более разумен, IMO, в качестве альтернативы вы можете создать публичный псевдоним метода:
Product.class_eval do
alias_method :public_build_variants, :build_variants_from_option_values_hash
public :public_build_variants
end
Который теперь можно было использовать как
p = Product.new
p.public_build_variants
public :public_build_variants
, есть ли какая-то причина, по которой я мог бы избежать прямого изменения видимости метода, а не его псевдонима (другими словами: public :build_variants_from_option_values_hash
)?
Подход с переопределением видимости метода в ruby
не годится. Но, тем не менее, вы можете сделать это, получив и переопределив тот же метод для публичного пространства следующим образом:
class CC
private
def private_method
end
end
CC.new.private_method # => NoMethodError: private method `private_method' called for #<CC:0x8166144>
method = CC.instance_method(:private_method)
CC.send(:remove_method, :private_method)
CC.send(:define_method, :private_method, method)
CC.new.private_method # => nil
Но правильный способ вызвать частный метод - использовать открытый метод #send
следующим образом:
object.send :private_method, *args
#send
, битовый псевдоним или get/assign =)
send
является лучшим подходом, я полностью открыт на 100%, если вы хотите помочь мне понять вашу позицию. Как я уже сказал, оба метода казались мне более или менее одинаково хорошими, если не считать упомянутой мною вещи "чистоты". Как вы думаете, почему #send
может быть лучшим подходом?
Похожие вопросы
Новые вопросы
ruby-on-rails
Ruby on Rails - это полнофункциональная платформа веб-приложений с открытым исходным кодом, написанная на Ruby. Он следует популярной модели фреймворка MVC и известен своим подходом «соглашение поверх конфигурации» при разработке приложений.
send :private_method, *args
?