Sto cercando di capire la funzionalità dei miglioramenti di Ruby e ho riscontrato uno scenario che non capisco.I perfezionamenti si applicano solo ai metodi di istanza?
Prendete questo codice di esempio:
class Traveller
def what_are_you
puts "I'm a Backpacker"
end
def self.preferred_accommodation
puts "Hostels"
end
end
module Refinements
module Money
def what_are_you
puts "I'm a cashed-up hedonist!"
end
module ClassMethods
def preferred_accommodation
puts "Expensive Hotels"
end
end
def self.included(base)
base.extend ClassMethods
end
end
refine Traveller do
include Money
end
end
Ora, quando faccio questo nel REPL:
Traveller.new.what_are_you # => I'm a Backpacker
Traveller.preferred_accommodation # => Hostels
using Refinements
Traveller.new.what_are_you # => I'm a cashed-up hedonist!
Traveller.preferred_accommodation # => Hostels (???)
Perché #what_are_you
raffinati, ma .preferred_accommodation
non lo è?
'Traveller.preferred_accommodation' è un metodo di classe. 'Traveller.new.preferred_accommodation' stamperà ciò che ti aspetti (dato che hai una classe base estesa sull'inclusione). Ma 'Traveller' è un'istanza della classe' Class'. Se vuoi che 'Traveller.preferred_accommodation' sia raffinato, devi ridefinire' Class' class_. – mudasobwa
@mudasobwa, potresti farlo, ma non renderebbe disponibili le raffinate versioni dei metodi a tutte le classi? Non è lo stesso problema della creazione di metodi di classe definendo metodi di istanza sulla classe 'Class': diventano metodi di classe per tutte le classi? Non riesco a vedere alcun vantaggio nel fare ciò oltre la raffinazione delle classi singleton e gli ovvi svantaggi. –
@CarySwoveland Sicuramente hai ragione. Direi che ** non deve ** essere fatto con la raffinatezza di 'Class'; il motivo per cui ho lasciato cadere il commento e non una risposta è: volevo fare luce su cosa sta succedendo, ma non dare una ricetta pratica. – mudasobwa