@toshi_a world_settingの中でDeferred.fail("message")すると uncaught throw :__deferredable_fail で落ちるのはどうしてでしょうか? core/plugin/change_account/change_account.rbのon_request_world_addではdialogDSLでアカウント追加ダイアログを出して、.trapで拾っているように見えるんですが……

@cobodo Deferredのバグで滅多に問題にならないやつで、ThreadのなかでDeferred.#failを使ったら死ぬというのがあるので、多分それですね。
回避方法としては適当な例外をraiseする(trap節で例外オブジェクトを受け取れる)というのがあります。
Deferred.#failも専用の例外をraiseするように書き換えようと思っています。ついに指摘されたから今日絶対やる(使命感)

フォロー

@toshi_a やりたいことは、ユーザーの入力内容によっては(それが妥当でないことを示して)world作成を中止する、ということなんですが、Deferred.failを使う以外の推奨する方法はありますか? なければ修正を待ちます。

@cobodo 適当な例外クラスを定義して

Deferred.next{
raise TeokureError, "too late"
}.trap{|exc|
p exc.class # TeokureError
p exc.message # "too late"
}

みたいな。TeokureErrorに適当なメンバ変数とアクセサを用意しておけばString以外の値も渡せます。受け取った後はDefered.failがうまく言った場合とやることは同じですね

@toshi_a いえ、Deferred一般の話ではなくて、world_settingの話です。

@toshi_a world_settingでも何か適当な例外クラスを定義してraiseしてやれば当座はしのげるだろうということはわかったんですが、world_settingとして推奨する方法が知りたい、ということです。

@cobodo world_settingがbreakする仕組みは持ってない気がしますね。エラーメッセージを表示する方法については大丈夫ですか(なさそう)

@toshi_a
label 'アカンやでw'
await_input
Deferred.fail('死んだよ')
next
くらいでいいかなと思っていますが、on_request_world_add側で面倒見てくれれば、よりラクができるな、とも思いますね。

@cobodo それでいうなら

await_input
if fail
label "死んだよ"
next
end
# 正常処理の続き

みたいに書きますね。課題と言えば課題なのかもしれないけど、そんなに長かったり入力量が多かったりするものは想定してないです

@cobodo あーそれは分かってるのか。dialog DSLのウィザード機能はそんなに高レベルな機能を提供することは想定していなくて、将来何らかの形でウィザードに特化したDSLをwrapする人が、必要なら現れるんじゃないかなーと思っています。俺はあんまり要らないと思う

@toshi_a 了解です。
ちなみに、world_settingから離れてdialog DSL一般の話として、キャンセルを押したことにさせることってできますか? 例えばOKが押されたときにキャンセルしたことにさせるには
await_input
destroy
とかでできますか?

@cobodo なんかあった気もするけど覚えてないな。あとさっきのThread内でDeferred.failが効かない問題は訂正があって、そもそもDialog DSLはDeferredを使ってないのでDeferred.failが使えないというのが正確な説明です。よってとりあえずの回避方法として紹介した方法しか使えません

ログインして会話に参加
金具

Mastodon は、オープンなウェブプロトコルを採用した、自由でオープンソースなソーシャルネットワークです。電子メールのような分散型の仕組みを採っています。