2009-08-26 11 views
3

Ich möchte die Standardargumente ändern, die an eine Ruby-Funktion übergeben werden. Zum Beispiel das Schreiben statt jedes MalÄndern der Standard-Ruby-Argumente

[1,2,3].do_stuff(:option => ' my option ') 

möchte ich die Standardeinstellungen ändern, so dass ich

[1,2,3].do_stuff 

schreiben Was die einfachste ist, sauberste, Rubin artig Standardparameter ändern ?

Antwort

2
>> [1, 2, 3].do_stuff 
=> Result I get 
>> [1, 2, 3].do_stuff :an_option => a_value 
=> Result I really want, but don't want to specify the argument 

Ich mag super für diesen Einsatz. Es ermöglicht uns, einige Funktionen der Methode hinzuzufügen, abgesehen von nur die Änderung Standardargumente:

class Array 
    def do_stuff(options = {}) 
    # Verify if caller has not passed the option 
    options[:argument_i_want_to_change] = default_value_i_want unless options.has_key? :argument_i_want_to_change 
    # call super 
    super 
    end 
end 

Ergebnis:

>> [1, 2, 3].do_stuff 
=> Result that I really want 

UPDATE: Entfernte reverse_merge! Abhängigkeit. (Jetzt suchen Sie nach besseren Alternativen zur Verwendung von [] = Methode)

0

Sie wollen eine Lösung für Code, den Sie nicht selbst geschrieben haben? Ich kenne zwei Möglichkeiten.

Code, den Sie schrieb selbst:

def some_method_you_wrote(options) 

wird:

def some_method_you_wrote(options = { :option1 => 'value' }) 

(Swanand Antwort ist zu nett)

Für Code, den Sie nicht schreiben, schauen Sie in Aliasing Methoden. (Rails bietet etwas genannt alias_method_chain für diesen Zweck, IIRC.)

+0

Das Problem bei diesem Ansatz ist, dass die Option 'option1' nicht gesetzt wird, wenn sie einen Hash von Optionen ohne den Schlüssel 'option1' übergeben. – Benjamin

1

(bewegte sich von Ihrer ursprünglichen Frage)

Ich nehme an, Sie sprechen über eine Methode Array # do_stuff die bereits vorhanden ist, aber Sie wollen es leicht ändern (in Ihrem Fall durch Ändern eines Standardparameters).

Ein Beitrag here gibt eine nette Möglichkeit, es zu tun. Es leidet nicht an den gleichen Problemen wie die Alias-Technik, da es keine übriggebliebene "alte" Methode gibt.

Hier, wie Sie diese Technik mit Ihrem Beispiel Problem verwenden könnte (mit Ruby getestet 1,9)

class Array 
    old_do_stuff = instance_method(:do_stuff) 
    define_method(:do_stuff) { |options = {}| 

    options[:option] ||= " option " 
    old_do_stuff.bind(self).call(options) 
    } 
end 

Sie möchten vielleicht auch bis auf UnboundMethod lesen, wenn der obige Code verwirrend ist. Beachten Sie, dass old_do_stuff nach der Endanweisung den Gültigkeitsbereich verlässt. Dies ist also kein Problem für zukünftige Verwendungen von Array.