“二変数を入れ替えるメソッド”を Squeak Smalltalk と Rubinius Ruby で


各言語間の参照と値渡し - @author pyridoxin に対する Squeak Smalltalk と、Smalltalk 指向の Ruby 処理系である Rubinius を使った解答。例によって実行コンテキストをぐりぐりいじるパターンで。


Squeak Smalltalk

Symbol >> swapWith: anotherTempSym
    | sender tempIndex1 tempIndex2 savedValue |
    sender := thisContext sender.
    tempIndex1 := sender tempNames indexOf: self.
    tempIndex2 := sender tempNames indexOf: anotherTempSym.
    savedValue := sender tempAt: tempIndex1.
    sender tempAt: tempIndex1 put: (sender tempAt: tempIndex2).
    sender tempAt: tempIndex2 put: savedValue
| a b |
a := 1.
b := 2.
#a swapWith: #b.
^{a. b}   "=> #(2 1) "

■ Rubinius Ruby

module Kernel
  def swap(local_sym1, local_sym2)
    sender = MethodContext.current.sender
    sender = sender.home if BlockContext === sender
    local_idx1 = sender.method.local_names.to_a.index(local_sym1)
    local_idx2 = sender.method.local_names.to_a.index(local_sym2)
    saved_val = sender.locals[local_idx1]
    sender.locals[local_idx1] = sender.locals[local_idx2]
    sender.locals[local_idx2] = saved_val
  end
end

a = 1
b = 2
swap(:a, :b)
p [a, b]   #=> [2, 1]