Comment puis-je modifier la valeur de retour d'un constructeur de classe dans Ruby?
J'ai une classe, Toto. Je veux être en mesure de passer le constructeur Foo exemple, foo et obtenir la même instance.
En d'autres termes, je veux que cette épreuve à passer:
class Foo; end
foo = Foo.new
bar = Foo.new(foo)
assert_equal foo, bar
Ce que quelqu'un sait comment je peux faire? J'ai essayé ceci:
class Foo
def initialize(arg = nil)
return arg if arg
end
end
foo = Foo.new
bar = Foo.new(foo)
assert_equal foo, bar # => fails
mais ça ne fonctionne pas.
Aider?
MODIFIER
Parce qu'un certain nombre de personnes ont demandé mon raisonnement:
Je suis en train de faire une analyse rapide de grandes quantités de données (de nombreux TB) et je vais avoir un grand nombre de cas de beaucoup d'objets. Pour certains de ces objets, il n'est pas logique d'avoir deux instances différentes avec les mêmes données. Par exemple, un tel objet est une "fenêtre" (comme dans la fenêtre temporelle) de l'objet qui a deux propriétés: l'heure de début et de fin des temps. Je veux être en mesure d'utiliser le constructeur de l'une des manières suivantes et obtenir un objet de la fenêtre dos:
window = Window.new(time_a, time_b)
window = Window.new([time_a, time_b])
window = Window.new(seconds_since_epoch_a, seconds_since_epoch_b)
window = Window.new(window_obj)
window = Window.new(end => time_b, start => time_a)
...
Un autre objet qui a besoin d'une fenêtre peut être instancié de cette façon:
obj = SomeObj.new(data => my_data, window => window_arg)
Je n'ai pas forcément savoir ce qui est dans window_arg, et je n'ai pas vraiment de soins -- il acceptera n'importe quel argument qui peut être interprété par le constructeur de Fenêtre. Dans le cas d'avoir déjà une Fenêtre de l'instance, je préfère suffit d'utiliser cette instance. Mais le travail d'interprétation qui semble être une préoccupation de la Fenêtre constructeur. De toute façon, comme je l'ai mentionné, je suis barattage travers plusieurs to de données et création d'un grand nombre d'instances de choses. Si un objet de la fenêtre passe autour de moi, je veux qu'il vient d'être reconnu comme un objet de la fenêtre et utilisé.
source d'informationauteur Sir Robert
Vous devez vous connecter pour publier un commentaire.
Par définitionles constructeurs sont destinés à retourner un objet nouvellement créé de la classe, elles sont un membre de, de sorte que, non, vous devriez pas remplacer ce comportement.
En outre, en Ruby,
new
appelsinitialize
quelque part à l'intérieur de son corps de la méthode, et sa valeur de retour est ignorée, donc de toute façon la valeur de retour deinitialize
ne seront pas retournés à partir denew
.Avec cela dit, je pense que dans votre cas, vous souhaiterez peut-être créer une usine méthode qui renvoie différentes
Foo
des objets en se basant sur les arguments passés à la méthode de fabrique:initialize
est appelé parnew
qui ignore sa valeur de retour. Fondamentalement, la valeur par défautnew
méthode ressemble à ça (sauf que c'est implémenté en C, pas en ruby):De sorte que le nouvellement allouée objet est retourné de toute façon, peu importe ce que vous faites dans
initialize
. La seule façon de changer qui supplante l'new
méthode, par exemple comme ceci:Cependant j'avais fortement déconseillé car cette mesure va à l'encontre de beaucoup d'attentes que les gens ont lors de l'appel de
new
:new
pour renvoyer un nouvel objet. Je veux dire, c'est même appelénew
. Si vous voulez une méthode qui ne permet pas toujours de créer un nouvel objet, vous devriez probablement appeler quelque chose d'autre.Foo.new
retour d'unFoo
objet. Votre code sera de retour quel que soit l'argument est. I. e.Foo.new(42)
serait de retour 42, un Entier, pas unFoo
objet. Donc, si vous allez pour ce faire, vous devriez à tout le moins que le retour de l'objet donné, si c'est unFoo
objet.Ne fonctionne pas pour:
Pour ce cas d'utilisation particulier, il pourrait être préférable d'utiliser l'une de ces approches.
Cela vous permet de n'avoir qu'un seul objet qui est créé, qui peut être utilisé de manière universelle, mais renvoie un
Foo
objet, le rendant à la baisse de plus en plus en ligne avec les attentes normalisées d'unnew
méthode, comme Jacob l'a souligné.