Ich benutze das manchmal, wenn ich etwas einer Variablen zuweisen möchte, aber ich muss den Wert berechnen, den ich zuerst zuweisen möchte. Es macht den Code auf diese Weise ein bisschen aufgeräumter. Ich denke, es ist Benutzervorliebe. Im Grunde sagst du: Ich gebe foo etwas zu, aber um den Wert zu bekommen, den ich will, muss ich zuerst einige Dinge tun. Es ist besonders nützlich, wenn memoization tun, so dass anstelle von
if @cache.nil?
do_something!
@cache = read_value
end
Sie tun können
@cache ||= begin
do_something!
read_value
end
Was Sie nehmen hier den Vorteil, dass die Ruby-Interpreter einen Stapel hat, und jeder Ausdruck wird in der Regel etwas auf Push der Stapel, oder nimm etwas vom Stapel. Die Zuweisung nimmt nur das letzte vom Stapel und ordnet es zu (in diesem Fall die letzte Zeile von Anfang/Ende). Oftmals kann dies nützlich sein (Stack-Ansatz in Ruby).
Ich denke nicht, dass es am wenigsten Überraschung verletzt, aber ich denke, es ist Benutzervorliebe, ob Sie es verwenden wollen oder nicht.
können Sie sehen, dass es nichts tut unerwartet bei der Suche, was Bytecodebefehle es erzeugt in Ruby MRI 1,9:
RubyVM::InstructionSequence::compile("c = begin; a = 5; 6; end").to_a
[:trace, 1],
[:trace, 1],
[:putobject, 5],
[:setlocal, 2],
[:trace, 1],
[:putobject, 6],
[:dup],
[:setlocal, 3],
[:leave]
Trace nur für Stack-Traces ist, können Sie das ignorieren. Dup dupliziert das letzte Element auf dem Stapel. In diesem Beispiel ist die Nummer der lokalen Variablen a
2
und die Nummer der lokalen Variablen c
ist 3
(daher wird putobject, 2
der Variablen a
zugeordnet usw.). Der einzige Nebeneffekt davon im Vergleich zu a = 5; c = 6
ist die dup
Anweisung, was bedeutet, dass die Stackgröße Ihrer Methode um 1 Slot größer ist. Dies ist jedoch nicht besonders wichtig, da es nur Auswirkungen hat, während der Interpreter in dieser speziellen Methode ist und der Speicher für den Stapel sowieso vorreserviert ist. Das bedeutet also nur, dass der Stapelzeiger um 1 mehr dekrementiert wird als sonst. Also grundsätzlich keine Veränderung. Mit optimierten Optimierungen wird wahrscheinlich auch die dup
verschwinden.
Ich habe noch nie einen solchen Code gesehen. Können Sie auf eine öffentliche Quelldatei zeigen? –
@SergioTulentsev: bis ich eine Quelldatei finden kann, hier ist ein Blog-Kommentar: http://blog.rubybestpractices.com/posts/rklemme/003-The_Universe_between_begin_and_end.html # comment-9011441 – pje
Ich weiß nicht, wie es gefährlich wäre, aber IMO ist es falsch: es sollte eine Methode sein. –