わかりにくい業務連絡です。
懸念 4 つのうち 1 つがほぼ完了しました。20 日締め切りのが一本残ってますが、これは土日で終わりそう。
原稿も 23 日までのやつはなんとかなりそうな見通し。
るびまの添削記事は今夜と思ってたけど明日 (土曜日)。
いま原稿がどーのこーのとか言ってる時点で明らかですが、『ふつうの Haskell プログラミング』の出版は五月にのびてしまいました。遅くても四月でいけるだろうと思ってたんですが、ゴールデンウィークがあるから四月に出すには普通より早く校了してないとだめだそうで、五月になってしまいました。楽しみにしてくださっているかたには申し訳ない。
(03:00)
http://mypage.odn.ne.jp/www/k/8/k8_hammer_trans/files/Hammer-Info.html
3.0 GHz Opteron 近く登場へ 13日に行われるというDual-core Opteron 2xxの新価格がリークされている。265は半値以下になるようだ。3月には285 (たぶん2.6GHz dual-core) が出るという。また、256 Opteronというのも登場するようだ。これまでのMNからすると、ついに3.0 GHzに到達することになる。
マジデスカッ!ベンダ価格が $327 ということは市場価格は 4〜5 万くらいになるのかな。これは Opteron dual core dual を組む絶好のチャンスがキター!でも金がないっ。
(21:21)
http://i.loveruby.net/autobuild/yarv/
現時点で YARV には Ruby の test/ruby + rubicon の一部 + 自前テストが入っていて、Ruby の仕様はほぼすべてカバーしてます。つまり、このグラフの赤色・黄色がなくなればほぼ Ruby 1.9 に追い付いたことになります。
(01:06)
どうしてこれが動かないのかと思ったら……
require 'delegate' class Aend class B < DelegateClass(A) def initialize super A.new endend class C < B def m puts "C, OK" endend C.new.funcall(:m) # NoMethodError???
funcall を delegate.rb がフックしてて、勝手に NoMethodError にしてくれてました。ついでに inspect までデレゲートしてくれたおかげでデバッグしにくいのなんのって。Rails の奥底でこれにはまったおかげで 4 時間もかかったよ。知らねーうちにレシーバがすりかわってる (ように見える) んだもんな。しかもデレゲート先と引数が偶然同じだったがために余計なところをえんえんひきずりまわされてさ。この仕様はつくづく許しがたい。
(07:48)
YARV で Rails。なんとか最初の自動生成は通った (通した) んだが、WEBrick を起動した瞬間に落ちた。このさい WEBrick をあきらめてCGI でなんとかするほうが早いかな。
さて Rails で CGI はどーすんのかなー。
(08:04)
public/dispatch.cgi という怪しげなファイルを発見!
/var/www/rails/testsite % ./public/dispatch.cgi aamine@serenadeDBG> : "/usr/local/pkg/yarv/lib/ruby/gems/1.9/gems/actionpack-1.11.2/lib/action_controller/code_generation.rb:159:in `finish'"DBG> : "/usr/local/pkg/yarv/lib/ruby/gems/1.9/gems/actionpack-1.11.2/lib/action_controller/code_generation.rb:137:in `go'"DBG> : "/usr/local/pkg/yarv/lib/ruby/gems/1.9/gems/actionpack-1.11.2/lib/action_controller/code_generation.rb:132:in `continue'" ……略…… c:0005 p:-001 s:0007 b:0007 l:0006 d:0006 FINISH i:- s: -c:0004 p:-001 s:0006 b:0006 l:0005 d:0005 CFUNC i:require s: -c:0003 p:0037 s:0003 b:0003 l:-861 d:-861 TOP i:<main> s: -c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:- s: -c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:- s: ----------------------------[BUG] Segmentation faultruby 1.9.0 (2006-02-14) [x86_64-linux]
そんなお約束なー!
(08:08)
わかったよー、追うよ追いますよ!
/var/www/rails/testsite % gdb -c core /usr/local/pkg/yarv/bin/rubyずばっと略 (gdb) bt#0 0x0000002a95d8fdd0 in raise () from /lib/libc.so.6#1 0x0000002a95d91280 in abort () from /lib/libc.so.6#2 0x0000002a9569d1b5 in rb_bug (fmt=0x2a9573d021 "Segmentation fault") at error.c:171#3 0x0000002a956f7ae0 in sigsegv (sig=11) at signal.c:467#4 <signal handler called>#5 th_invoke_proc (th=0x55d1d0, proc=0x11a7d80, self=0, argc=1, argv=0x2a96102550) at vm.c:666#6 0x0000002a9571e984 in proc_call (argc=1, argv=0x2a96102550, procval=182929376352) at yarv.h:49#7 0x0000002a9571c3bb in call_cfunc (func=0x2a9571e940 <proc_call>, recv=182929376352, len=0, argc=5624272, argv=0x0) at call_cfunc.h:24#8 0x0000002a9571a445 in th_eval (th=0x55d1d0, initial=0) at insns.def:1253#9 0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449#10 0x0000002a95717897 in th_call0 (th=0x55d1d0, klass=0, recv=182929388432, id=182902709320, oid=182906266960, argc=2, argv=0x2a96102468, body=0xc4d580, nosuper=0) at vm.c:425#11 0x0000002a956a507e in rb_call (klass=182916132936, recv=182929388432, mid=3977, argc=2, argv=0x2a96102438, scope=1) at yarv.h:49#12 0x0000002a9571a5b0 in th_eval (th=0x55d1d0, initial=0) at vm.c:1149#13 0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449#14 0x0000002a95717897 in th_call0 (th=0x55d1d0, klass=0, recv=182929400152, id=182902709320, oid=182906266960, argc=2, argv=0x2a961022f8, body=0xc4d580, nosuper=0) at vm.c:425#15 0x0000002a956a507e in rb_call (klass=182916132936, recv=182929400152, mid=3977, argc=2, argv=0x2a961022c8, scope=1) at yarv.h:49#16 0x0000002a9571a5b0 in th_eval (th=0x55d1d0, initial=0) at vm.c:1149#17 0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449#18 0x0000002a95717df6 in th_invoke_yield (th=0x55d1d0, argc=1, argv=0xfaffff21) at vm.c:640#19 0x0000002a956a40b6 in rb_yield_0 (val=182929495112, self=0, klass=0, flags=-1780884408, avalue=-1777326768) at yarv.h:49#20 0x0000002a9568fbe0 in rb_ary_each (ary=182929495392) at array.c:1147#21 0x0000002a9571c3c4 in call_cfunc (func=0x2a9568fb70 <rb_ary_each>, recv=182929495392, len=0, argc=5624272, argv=0x0) at call_cfunc.h:27#22 0x0000002a9571a445 in th_eval (th=0x55d1d0, initial=0) at insns.def:1253#23 0x0000002a9571c02d in th_eval_body (th=0x55d1d0) at vm.c:1449#24 0x0000002a95717897 in th_call0 (th=0x55d1d0, klass=0, recv=182929403472, id=182902709320, oid=182906266960, argc=2, argv=0x2a961021c0, body=0xc4d580, nosuper=0) at vm.c:425#25 0x0000002a956a507e in rb_call (klass=182916132936, recv=182929403472, mid=3977, argc=2, argv=0x2a96102190, scope=1) at yarv.h:49 以下略
とりあえず一番上のフレームを見てみる。
(gdb) f 6#6 0x0000002a9571e984 in proc_call (argc=1, argv=0x2a96102550, procval=182929376352) at yarv.h:4949 {(gdb) list44 return theYarvVM;45 }4647 static inline yarv_thread_t *48 yarv_get_current_running_thread(void)49 {50 return yarvCurrentThread;51 }5253 static inline void(gdb) p yarvCurrentThread$1 = (yarv_thread_t *) 0x55d1d0(gdb) p *$1$2 = {self = 182906065688, vm = 0x55d0a0, stack = 0x2a96102010, stack_size = 131072, cfp = 0x2a96200e90, safe_level = 0, state = 0, passed_block = 0x0, top_local_tbl = 0x0, base_block = 0x0, local_lfp = 0x0, local_svar = 0, thread_id = 182904806112, status = THREAD_RUNNABLE, priority = 0, native_thread_data = {dummy = 0}, thgroup = 182906060288, value = 0, wait_thread_value = 0, errinfo = 4, throwed_errinfo = 0, interrupt_flag = 0, tag = 0x7fbfffae00, parse_in_eval = 0, local_storage = 0xe8a8c0, signal_queue = {buff = {0 <repeats 16 times>}, head = 0, tail = 0}, signal_thread_list = 0x0, first_proc = 0, first_args = 0, machine_stack_start = 0x7fbffff600, machine_stack_end = 0x7fbfffc560, machine_regs = {{__jmpbuf = {5624568, 5624272, 5624272, 4, 182897364680, 1, 548682057072, 182895908384}, __mask_was_saved = 0, __saved_mask = {__val = {0 <repeats 16 times>}}}}, stat_insn_usage = 0, method_missing_reason = 0, abort_on_exception = 0}
GET_THREAD() の中に入っちゃってるな。これは意味なさそう。proc_call() の引数を見たほうがいいか。
(gdb) p 0x2a96102550$3 = 182906266960(gdb) p (VALUE*)$3$4 = (long unsigned int *) 0x2a96102550(gdb) p *$4$5 = 182929375032(gdb) rp $5T_STRING$6 = {basic = {flags = 7, klass = 182906235808}, len = 54, ptr = 0x12eb390 "{\"controller\" => controller_value, \"action\" => \"wsdl\"}", aux = {capa = 62, shared = 62}}(gdb) rp 182929376352T_DATA$7 = {basic = {flags = 18, klass = 182906068888}, dmark = 0x2a9571e860 <proc_mark>, dfree = 0x2a9571e840 <proc_free>, data = 0x11a7d80}(gdb) p $7.data$8 = (void *) 0x11a7d80(gdb) p (yarv_proc_t*)$8$9 = (struct {...} *) 0x11a7d80(gdb) p *$9$10 = {block = {self = 0, lfp = 0x0, dfp = 0x0, iseq = 0x0, proc = 0}, envval = 0, blockprocval = 0, safe_level = 0, is_lambda = 0, special_cref_stack = 0x0}
呼ぼうとした Proc の実体が初期化されてないのか……?
(08:30)
おーし、
require 'rubygems'require_gem 'actionpack' ActionController::Routing::Routes.draw do |map| map.connect ':controller/service.wsdl', :action => 'wsdl' map.connect ':controller/:action/:id'end
で再現。あとはどこまで短縮できるかだ。
(09:01)
特定完了
~/c/yarv/REPOS/actionpack % /usr/local/pkg/yarv/bin/ruby -e 'Proc.new{}.dup.call'DBG> : "-e:1:in `<main>'"-- stack frame ------------0x2a96102010 (0000): 000000010x2a96102018 (0001): 000000040x2a96102020 (0002): 2a960cf2980x2a96102028 (0003): 2a960cf2480x2a96102030 (0004): 00000001 <- lfp <- dfp-- control frame ----------c:0004 p:-001 s:0005 b:0005 l:0004 d:0004 CFUNC i:call s: -c:0003 p:0025 s:0003 b:0003 l:-815 d:-815 TOP i:<main> s:c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:- s: -c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:- s: ----------------------------[BUG] Segmentation faultruby 1.9.0 (2006-02-14) [x86_64-linux] zsh: 24815 abort (core dumped) /usr/local/pkg/yarv/bin/ruby -e 'Proc.new{}.dup.call'
(09:53)
そうか……ということはこれでも落ちるだろうなあ。
~/c/yarv % ./ruby -e 'Proc.allocate.call'DBG> : "-e:1:in `<main>'"-- stack frame ------------0x2a96102010 (0000): 000000010x2a96102018 (0001): 000000040x2a96102020 (0002): 2a960cf4a00x2a96102028 (0003): 2a960cf4780x2a96102030 (0004): 00000001 <- lfp <- dfp-- control frame ----------c:0004 p:-001 s:0005 b:0005 l:0004 d:0004 CFUNC i:call s: -c:0003 p:0019 s:0003 b:0003 l:-811 d:-811 TOP i:<main> s: -c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:- s: -c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:- s: ----------------------------[BUG] Segmentation faultruby 1.9.0 (2006-02-14) [x86_64-linux] zsh: 24828 abort (core dumped) ./ruby -e 'Proc.allocate.call'
やはり。ということは、こんなのとか、
~/c/yarv % ./ruby -e 'p YARVCore::InstructionSequence.allocate'DBG> : "-e:1:in `p'"DBG> : "-e:1:in `<main>'"-- stack frame ------------0x2a95ee2010 (0000): 000000010x2a95ee2018 (0001): 000000040x2a95ee2020 (0002): 2a95eaf4500x2a95ee2028 (0003): 2a95ede4080x2a95ee2030 (0004): 2a95eaf4280x2a95ee2038 (0005): 000000010x2a95ee2040 (0006): 00000001 <- lfp <- dfp-- control frame ----------c:0005 p:-001 s:0007 b:0007 l:0006 d:0006 CFUNC i:inspect s: -c:0004 p:-001 s:0006 b:0006 l:0005 d:0005 CFUNC i:p s: -c:0003 p:0022 s:0003 b:0003 l:-093 d:-093 TOP i:<main> s: -c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:- s: -c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:- s: ----------------------------[BUG] Segmentation faultruby 1.9.0 (2006-02-14) [x86_64-linux]
こんなのとか、
~/c/yarv % ./ruby -e 'p YARVCore::VM.allocate.eval(YARVCore::InstructionSequence.allocate)'DBG> : "-e:1:in `eval'"DBG> : "-e:1:in `<main>'"-- stack frame ------------0x2a95ee2010 (0000): 000000010x2a95ee2018 (0001): 000000040x2a95ee2020 (0002): 2a95eaf2e80x2a95ee2028 (0003): 2a95ede4080x2a95ee2030 (0004): 2a95eaf2c00x2a95ee2038 (0005): 2a95eaf2980x2a95ee2040 (0006): 000000010x2a95ee2048 (0007): 000000010x2a95ee2050 (0008): 00000001 <- lfp <- dfp-- control frame ----------c:0006 p:-001 s:0009 b:0009 l:0008 d:0008 TOP i:(null) s: -c:0005 p:-001 s:0008 b:0008 l:0007 d:0007 FINISH i:- s: -c:0004 p:-001 s:0007 b:0007 l:0006 d:0006 CFUNC i:eval s: -c:0003 p:0037 s:0004 b:0003 l:-083 d:-083 TOP i:<main> s: -c:0002 p:-001 s:0001 b:0001 l:0000 d:0000 FINISH i:- s: -c:0001 p:-001 s:0000 b:-001 l:0000 d:0000 ------ i:- s: ----------------------------[BUG] Segmentation faultruby 1.9.0 (2006-02-14) [x86_64-linux]
こんなのもヤバげということに……
~/c/yarv % ./ruby -e 'p eval("", YARVCore::VM::Binding.allocate)'-e:1:in `eval': -e:1:in `eval': wrong argument type false (expected Data) (TypeError) from -e:1:in `<main>' ~/c/yarv % ./ruby -e 'eval("", binding().dup)'-e:1:in `eval': -e:1:in `eval': wrong argument type false (expected Data) (TypeError) from -e:1:in `<main>'
(10:23)
/var/www/rails/testsite % /usr/local/pkg/yarv/bin/ruby script/server=> Booting WEBrick...=> Rails application started on http://0.0.0.0:3000=> Ctrl-C to shutdown server; call with --help for options[2006-02-20 10:40:23] INFO WEBrick 1.3.1[2006-02-20 10:40:23] INFO ruby 1.9.0 (2006-02-14) [x86_64-linux][2006-02-20 10:40:23] INFO WEBrick::HTTPServer#start: pid=25032 port=3000
動いちゃったよ……。
(10:46)
http://jp.rubyist.net/magazine/?0013
るびま 13 号出た。わたしは添削の 3 回目を書きました。
今回の添削はクソ長いです。あの添削は毎回長いんですが、それでもなんとか 30KB くらいだったのが今回はなんと 50KB 超。「ふつりな」サイズで約 50 ページに相当します。本なら二章に分けるとこですがウェブだからいいやってことで 1 ページにぶちこみました。スクロールバーのバー部分の小ささに絶望を感じていただきたいと思います。
ライブラリ紹介、今回は net/http かあ。実はちゃんと読んでないんですけど。net/http も結構やらないかんことが残ってるんだよな。もう To Do がたまりすぎてスラッシング起こしてます。5 月になれば久しぶりにいろいろやれるんじゃないかと思うんだけども。
YAML 連載が完結。YPath なんてのがあるのか。いまだに YAML は samidare の config.yml の範囲しか使えない。この機に、せめて文法くらいは覚えようか。
Rails。YARV で動かすために SEGV の元を求めてソースコードを右往左往したんですが、ディレクトリの上のほうでまとめてモジュールを include するのはどうにかならんのですかー。
(12:23)
てやっ scaffolding
とかやってたら面白くて、使いもしないアドレス帳を作りこんでしまった……。と、いうくらい何も起きない。おかしい。ここは SEGV するのがお約束だろう。
などと言いつつ本当はすでに二回 SEGV している。しているが、一つめの protected なバグはその場で笹田さんに直してもらった。二つめは ObjectSpace 絡みで嫌だったのでちょっとズルして回避した。それ以降は何も起きてない。
しかし Rails って本当によくできてるな。エラーメッセージを見ながらいじっていくだけで動くというのが恐ろしい。これなら流行るのもわかる。
(11:00)
http://www.lostway.org/~tko/cgi-bin/bakagaiku.rb?bakaid=200602262
おかしいな、うちでは何も起こらない。
~/c/stdhaskell % cat trequire 'test/unit' class YarvTest < Test::Unit::TestCase def test_yarv assert(true) endend ~/c/stdhaskell % ~/tmp/yarv/bin/ruby -v truby 2.0.0 (Base: Ruby 1.9.0 2006-02-14) [x86_64-linux]YARVCore 0.4.0 Rev: 474 (2006-02-23) [opts: ]Loaded suite tStarted.Finished in 0.000292 seconds. 1 tests, 1 assertions, 0 failures, 0 errors
Pentium 4 だとダメという話があったけど、そのせいだろうか。あと、いまのリビジョンは gcc 4 だとバグが出ます。って、成果報告会で笹田さんが言ってた。
(19:39)
原稿書き。あと 2KB で 150KB。
その合間に FF5 をやる。なにもかもが懐かしい……。
第二世界 (ガラフの故郷) 開始しばらくあと。バル城の地下で石像相手にレベル 5 デスを連発し、ひたすら ABP を稼ぐ。と同時に全員で「ぬすむ」を連発してツインランサーを強奪する。ドラクエで勇者が人の家をあさりまくっていることの矛盾はつとに指摘されるところだが、モンスターの金品を強奪して省みない主人公たちもどうかと思う。
そんなどうでもいいことを考えているあいだにバッツが忍者マスターして「にとうりゅう」、ファリスが狩人マスターして「みだれうち」げとずさー。その勢いでついでに赤魔導師 (れんぞくま) もマスターしちゃう?とか思ったけが 500 ちょい稼いだところで飽きた。いくらなんでも ABP 999 は多すぎである。それゆえたいていの人は次元の狭間ラストフロアになってようやくれんぞくまをゲットするのだが、そのころになるともうほとんど使う相手がいないので結局あまり役に立たない。第二世界のエクスデスあたりで使えればめっちゃ便利そうなんだけどね。
エクスデスで思い出したが、エクスデスは本当に悪い奴なのだろうか?いまになってよくよく話を見ていると、実はエクスデスが悪いことをしているシーンが全然出てこない。ただガラフたちが「暗黒魔導師エクスデス!」とか言って倒そうとしているのでなんとなくそういうことになっているだけ。なにしろ本人は城のまわりにバリア張って出てこないのだ。まわりに全然被害を及ぼしていないではないか。もっと先も見るとなんかあるんだっけ?
さて二刀流ゲトしたので竜騎士で二刀流できる。なぜ槍は両手持ちできないのか、かねてから疑問だ。どう見ても剣より槍のほうが両手で持つの簡単だろ。ま、それはそれとして二刀流でジャンプするとダメージが合計 2000 を超えてる。さすがに強い。竜騎士は好きなのだが、あまり有意義なアビリティがないのが残念だ。
FF2 が初 FF のわたしとしては、竜騎士と言うと FF3 を思い出す(なんで FF2 のリチャードじゃないんだというツッコミは却下)。あれだよ、サロニア城でガルーダ相手に竜騎士でジャンプしまくるアレ。FF3 はほとんどイベント専用みたいなジョブが多くてなんでした。魔導師ハイン (バリアチェンジするやつ) → 学者、とか。そういや FF5 でもアルケオエイビスとかメリュジーヌがさりげなくバリアチェンジしてるけど、軽やかにスルーされるんだよな。あれは攻撃だけでも倒せるから。確かハインは通常攻撃がほとんど効かなかった。
飛竜の谷へ行く。ここは確かゾンビ系の敵が多かったような気がするな。気がするので、レクイエム目当てに魔法剣士レナを吟遊詩人にジョブチェンジする。たいていの人はここで吟遊詩人を使って「うわ、ちょー使えるじゃん」と認識を新たにするのだが、そのあとは役に立たないもんでやっぱりお蔵入りになるのである。
それにしてもつくづく FF5 のキャラはよいこばかりだ。よいこで思い出すのは DQ7。世間では評判の悪い DQ7 だが俺はわりと好きである。ただマリベルがいない期間はかなり辛かった。なにしろ仲間に話しかけても普通のことしか言ってくんないんだもん。ガボとかアイラとか名前すら忘れたじいさんとか、いらん。主人公、キーファ、マリベルの三人で最後までクリアしたかったよ。
今日はここまで。
(00:10)
そういや Ripper は動くのかな?とか思って何も考えずにつっこんだら make test-all TESTS=ripper で SEGV。キター。
search_method → st_lookup で落ちてる。つーことはクラスの m_tbl が壊れてるのか。
ウギャー、引数がほとんど壊れてる!こんなんでわかるか!
……SEGV 追ってる暇はないんだった。当面放置。
(12:22)
Wiki のために行指向パーサが欲しくなったので、Parsec を使って書いてみた。手間取るかと思ったが Text.ParserCombinator.Parsec.Charのコードをそっくり真似て書いたらあっさり動いてしまった。
module LineParser (LineParser, indented, blank, firstChar, anyLine) where import Text.ParserCombinators.Parsec.Primimport Text.ParserCombinators.Parsec.Posimport TextUtilsimport Data.Char (isSpace) type LineParser st a = GenParser String st a indented = firstChar isSpace blank = satisfy (null . strip) firstChar f = satisfy (testFirstChar f) testFirstChar f "" = FalsetestFirstChar f (c:_) = f c anyLine = satisfy (const True) satisfy :: (String -> Bool) -> LineParser st Stringsatisfy f = tokenPrim (\s -> show s) (\pos s ss -> incSourceLine pos 1) (\s -> if f s then Just s else Nothing)
さっそくこれを使って Wiki パーサを書きなおしてみた。(以下パースのコードのみ抜粋)
compile :: String -> HTMLcompile str = case parse document "" (lines str) of Right ptext -> ptext Left err -> p [Text (escape $ show err)] -- must not happen document = do ss <- many block return (concat ss) block = (blank >> return []) <|> heading <|> ulist <|> olist <|> dlist <|> preformatted <|> paragraph heading = do line <- firstChar (== '=') let (mark, label) = span (== '=') line return $ h (length mark) [Text (escape $ strip label)] ulist = nestedList '*' ulolist = nestedList '#' ol nestedList mark xl = do items <- many1 itemLine return $ compileList items where itemLine = do s <- firstChar (== mark) ss <- many indented return $ join (s:ss) dlist = do lines <- many1 (firstChar (== ':')) return $ dl (concatMap compileItem lines) preformatted = do lines <- many1 indented return $ pre [Text . escape . join . unindentBlock $ lines] paragraph = do line <- anyLine lines <- many (firstChar isNoFunc) return $ p . compileText . join $ (line:lines) where isNoFunc = (`notElem` "=*#: \t\r\n\v\f")
すっきりした。
(23:27)
なにいーっ! youtube って you tube だったのか!なぜか最後の e が a に見えたらしく「ようつば」だとばっかり思ってた。
さらに言えば「よつばと!」と何か関係があるものだと思っていた。
(04:00)