Continuations are so much easier to grasp than 2ch and Japanese
ko1 (of YARV fame) pointed me to an interesting challenge on 2ch (the largest Internet forum in the world, in Japanese).
Given some #open() and #close() methods, you can define trivially
def open_block(fn) fh = open(fn) yield fh close(fh) end
which accepts a block, passes the file handler corresponding to a given filename and closes it when done (you'd normally use an ensure clause, but the original message carried the above definition). This is a standard idiom. Now, given a working #open_block, can you define #open and #close?
As I read that, I knew it would involve callcc. #open was trivial, #close seemed harder. Actually hard enough to deserve being done. I was game.
It was pretty late (~1AM), but callcc is always fun and anyway it would only take a few minutes to solve, so I quickly came up with
def _open(name); puts "open: #{name}"; "IO<#{name}>" end
def _close(name); puts "close: #{name}" end
def open_block(fn); fh = _open(fn); yield fh; _close(fh); end
open_block("hoge"){|x| puts "Got #{x}" }
def open(x)
callcc do |cc|
r = nil
open_block(x) do |fh|
r = callcc do |cc2|
fh.instance_variable_set("@_closecc", cc2)
cc.call(fh)
end
end
r.call
end
end
def close(x)
callcc do |cc|
x.instance_variable_get("@_closecc").call(cc)
end
end
a = open("foo")
puts "----"
close(a)
puts "end"
When run, it outputs
open: hoge Got IO<hoge> close: IO<hoge> open: foo ---- close: IO<foo> end
as desired.
Being pretty satisfied with that, I decided to reply to the original message on 2ch. This surely cannot be difficult, can it? I know these kanji, alright. I fill the name field. Mmh can do without the email address. OK. Now the contents; I just paste the Ruby code without adding any text: I'm not running the current Konqueror instance with XIM, and I'm too lazy to run another (GTK-based) browser just to be able to compose in Japanese with im-ja (I don't feel like writing somewhere else and pasting into the form either). Done. There's a large button; I can't read all the kanji but it surely means "submit". Mmmm a new page seems to ask for confirmation before sending and shows my message. One sec, the indentation is gone. Ugh.
Next try, wrapping this with a <pre> tag. No good. I'll just ask the guys on the Japanese Ruby channels. I'm told there's no way to do preformatted text in 2ch, but they often use double-width spaces to achieve that. And I'm given the following oneliner:
ruby -ibak -pne '$_.gsub(/ /, " ")' some_script.rb
This turns two consecutive spaces into a double-width one. Mmm, I had never used -iwhatever. For some reason it doesn't want to work. I'm getting tired... I've needed about 6 minutes to write the callcc thing, and it's been 4 times that much reading 2ch's FAQ, and then trying to get my indent right. I hand-replace the spaces in a vim session running inside an unicode-enabled terminal, and finally copy the code to X11's paste buffer with "*y ... surely that can't go wrong. But it does... the über-spaces have turned into random garbage when pasting them. I try the same on a gecko-powered browser. Great, no more garbage... but... the spaces are gone. I hate this. Back to the original form. I remove the garbage and insert the double-width spaces manually. Ugh. OK, we're almost there, it's only been over half an hour (or maybe closer to an hour??) since I wrote the code. Let's submit. We're almost there!
Then comes true happiness
ERROR:ブラウザ変ですよ
that is,
ERROR: your browser is weird!
I give up.
Learn from my mistakes. Keep off 2ch!!!
Keyword(s):[blog] [ruby] [continuation] [callcc] [2ch] [Japanese]
References:[My mind and continuations, callcc seen graphically]