1
votes

manière différente de créer des méthodes spécifiques à un objet dans ruby

Je connais une seule façon de créer des méthodes spécifiques à une instance dans ruby, c'est-à-dire

 class Test;end
 class << (obj1 = Test.new)
   def greet
     p 'Welcome'
   end
 end
 obj1.greet #    "Welcome"
 obj2 = Test.new
 obj2.greet # through error as,
 Traceback (most recent call last):
 NoMethodError (undefined method `greet' for #Test:0x0000564fb35acef0>)

ou

 class Test;end
 obj1 = Test.new
 class << obj1
   def greet
     p 'Welcome'
   end
 end
 obj1.greet #    "Welcome"
 obj2 = Test.new
 obj2.greet # through error as,
 Traceback (most recent call last):
 NoMethodError (undefined method `greet' for #Test:0x0000564fb35acef0>)

Ici, j'ai deux questions :

  1. Quelle est l'utilisation réelle de ce type de méthodes spécifiques aux objets?
  2. Quelles sont les autres manières de créer des méthodes spécifiques à un objet dans Ruby?


2 commentaires

Oui, (1) pourrait avoir une large utilisation, mais veuillez m'en fournir au moins quelques-uns.


(1) une utilisation courante du monde réel et quotidienne sont des «méthodes de classe». Ceux-ci sont définis sur l'objet de classe plutôt que sur sa classe (la classe Class ) afin de limiter leur portée à cet objet spécifique.


4 Réponses :


1
votes

Vous avez défini le bloc de classe comme class uniquement pour l'objet obj1 qui est spécifique à l'objet. La méthode greet n'est donc définie que pour l'objet obj1 et non pour les autres objets de la même classe.

Mieux vaut inspecter le modèle suivant

class Test
  attr_accessor :name

  def initialize(name)
    self.name = name
  end
end

obj1 = Test.new('test1')

class << obj1
  def greet
    puts self.inspect, self.object_id, self.name
    puts 'Welcome'
  end
end

obj1.greet
obj2 = Test.new
obj2.greet


3 commentaires

Il y a un Object # define_singleton_method pour cette magie, pas besoin d'utiliser define_method .


@halfelf Oui, define_singleton_method définira la méthode singleton pour l'objet mais je cède la place à la définition des méthodes d'instance à n'importe quelle classe afin que n'importe quelle instance puisse accéder à cette méthode. Correct si je rate quelque chose


@halfelf OP est intéressé par définir une méthode spécifique à un objet donc je vais éditer la réponse pour ajouter ce point



0
votes

Selon le commentaire @mu_is_too_short, une autre façon est,

class Test; end
obj1 = Test.new

def obj1.pancakes
  p 'Where is pancakes house?'
end

obj1.pancakes # "Where is pancakes house?"
obj2 = Test.new
obj2.pancakes
Traceback (most recent call last) :
NoMethodError
(undefined method `pancakes' for #<Test:0x0000564fb35ca310>)


0 commentaires

2
votes
obj.methods(false)
  #=> [:greet3, :greet4, :greet1, :greet2, :greet5] 
obj.methods.grep /greet/
  #=> [:greet3, :greet4, :greet1, :greet2, :greet5,
  #    :greet6, :greet7] 

2 commentaires

Ou simplement def obj.greet; 'salut' ; fin


@Stefan, je n'ai pas inclus cela parce que c'était couvert dans une autre réponse. En fait, j'ai écrit l'édition ci-dessus mais je ne l'ai évidemment pas sauvegardée.



1
votes

Un exemple de cas d'utilisation: supposons que vous ayez un code de production qui utilise un hachage comme structure de données. Au fil du temps, il semble qu'une classe aurait été un meilleur choix, car un comportement plus intelligent que la simple conservation des données est nécessaire - par exemple, les données doivent être validées. Ce code de validation n'a de sens que dans le contexte de ce hachage spécifique. Vous pouvez définir une méthode validate_username dans l'espace de noms public ou dans un module, mais def the_hash.validate_username; #code; end serait sans doute une meilleure solution.


0 commentaires