ミュータブルな Bignum とコンテキストの変更
お呼びでない…とは知りつつも、Squeak Smalltalk だとどうなのかなーと考えたので。
Squeak Smalltalk では、Ruby と違い、Ruby でいうところの Bignum にあたる LargePositiveInteger と LargeNegativeInteger (〜のインスタンス。正確には)はミュータブルなので、こんなふうなことができます。
| i | i := 12345678987654321. (1 to: i digitLength) inject: 111111111 into: [:result :each | i digitAt: each put: result \\ 256. result // 256]. ^{i. i * 111111111}
=> #(111111111 12345678987654321)
加えてコンテキストをたぐって、耳から手を突っ込んで奥歯をがたがた言わせることも可能です。
| i | i := 12345678987654321. thisContext tempAt: 1 put: 111111111. {i. i * 111111111}
=> #(111111111 12345678987654321)
あと、今回の 111111111 には使えませんが、後には凶悪な #become: というのも控えています(^_^;)。
| i | i := 12345678987654321. i become: 1111111111 copy. {i. i * 1111111111}
=> #(1111111111 1234567900987654321)
いずれもお好みで。(違)
解答が示されていたのでこちらも書いてみました。
LargePositiveInteger >> div: y | val | val := self // y. self assureUniClass. #(= *) do: [:sym | self class compile: ('{1} other ^val {1} other' format: {sym}). (self class >> sym literalAt: 1) value: val]. ^val
| i | i := 12345678987654321. i div: 111111111. {i = 111111111. i * 111111111}
=> #(true 12345678987654321)
なるほど。特異クラスで再定義するというものでしたか。