近況

コード実行

hanachin.hateblo.jp

前回: ✅ 雑にスクリプトを書くと動くことを確認できた

「サンプルコードをブラウザ上で試せるようにしたい」のようなissueをたてろ、という感じですが

  • WASM版のバージョンとRubyのバージョンの対応がわからない
    • まだRuby 3.2出てないので対応つけるもなにもない
    • ブラウザで動くのはある時点のheadという感じ
    • npmのパッケージの番号をlatest指定すればよさそうではある
  • 3.1のサンプルコードに実行ボタンみたいなものをつけると3.2で挙動が変わるような3.1のコードを実行したときに意図しない結果が返るかもしれない
    • masterに対応するような形にするため、bitclustにオプションを追加してRunボタンつける・つけないを選べるとよさそう
    • 一方これも3.2がリリースされたあとheadが3.3になると困ることもあるかもしれない
    • runtimeを表示すればいいのか?
      • いやRubyのバージョンとかWASM版とか言われてもブラウザで実行されているRubyは何で、こういうことは実行出来るんだけどどういうことが出来てどういうことができないか分かりづらさはある
  • ストーリーとしてはサンプルコード試してみたあと、書き換えてみてどうなるか試したい、という使い方があると思う
    • 現状編集出来るようにはしてみたものの書き換えたときにシンタックスハイライトがうまく効かない
    • シンタックスハイライターをブラウザ上でも動かすみたいな気力はない
  • このへんを全部ぽいっと丸投げするためにTry Ruby上にコードを渡すみたいな感じが出来ればいいんじゃないか...?
  • Try Rubyに丸投げであればバージョン云々の気配りをしなくてもよくなるかもしれない
  • issueたて...たて

るりま

めちゃくちゃPRマージされていてznzさん凄い

ちょっと最近出来ていないので、何が出来るかな〜と考えていてこのissueを眺めていた

github.com

雑な理解をまとめると

  • 見出しにはアンカーを書くための記法が用意されている
    • 例: ===[a:a] あ で見出し「あ」のid属性に a を指定
  • [[ref:d:glossary#a]] のような形で「あ」という見出しの用語集へのリンクを書ける
  • rdのソースコードからこの見出しのアンカーを抜き出してくる処理は RefsDatabase が行っている
  • 用語集は用語の音の見出しの直後にdlistで用語が定義されている
  • dlistの記法では見出しと違ってdtにidを振る記法はない

どうするといいのかな。

  • 同一のrdの中で同じ用語について別の説明をつけることはない
  • ユーザーはHTML5に対応しているブラウザを利用している

というのを前提条件にして用語から空白をgsubした値をid属性に勝手に設定してやってもいいかもしれない

RefsDatabase#extractRDCompiler#dt あたりを更新したらできそうなので今晩やってみるか〜

近況: RubyのWASM対応べんりそうなので、るりまにRUNボタンつける実装を試していた

何があると便利かな〜?と思って考えたけど思いつかなかったので一番手頃そうな、るりまにRUNボタンをくっつけるのを週末試していた。

Pull Request出すかは未定。

あったら便利な気がするけども...?

latestバージョン様限定機能みたいな感じならいいかも、しらんけど。

近況

登園準備

保育園に持っていくお着替え2セットとその日着る服と歯磨き用品、朝身支度をする間に用意するのは自分には難しいので

以下3点を5つ作り置きすることにした。

  • お着替え2セットが入った袋
  • 歯磨き用品が入った袋
  • その日着る服

これによって朝行うのが

  • 持っていくお洋服を2セット用意する
    • シャツを用意する
    • ズボンを用意する
    • 靴下を1組用意する
    • なお前日に着替えていない洋服がある場合は足りないぶんを補充するため確認する
  • 歯磨き用品を用意する
    • 前日使ったコップがあれば出して洗う
    • 歯ブラシも洗う
    • 歯磨き粉を洗う
    • 前日使ったであろう歯ブラシを学校に忘れてきた場合、コップ・歯ブラシ・歯磨き粉を1セット用意する
  • その日着る服を持っていくお洋服同様用意する
  • 水筒を用意する

から

  • その曜日のお洋服セットを入れる
  • その曜日の歯磨き用品を入れる
  • その曜日の着る洋服セットを取り出す
  • 水筒を用意する

に減る

前日の残りを考慮する部分と、歯ブラシの衛生を保つ部分と、靴下を1組用意する部分は特に難しいのでこれを考慮しないでよくなった。 他、水筒についても替えの水筒を前日に用意する、用意されていなければ朝用意する、という感じでだいぶ難しいので5セット用意したほうがいいかもしれない。 リュックサックを5セットはやらない予定でいたが、やったほうが災害時に逃げ出す際に便利かもしれない。(平日であれば子供のリュックサックを何個か持つだけで子どものぶんの衣料は秒で確保できる)

「この袋はいつの袋だっけ?」が発生すると思うので曜日がわかりやすくなるような工夫をする。

靴下に関してはたとえ朝だろうが前日だろうが週末だろうが、組を用意する際に柄合わせをすると大変なので、無印良品で1日3足想定で、計15足を用意した。 使っててたりなくなったぶんぐらいは探してもいいかなあ(3足ぐらいかけたら多分補充する) 西松屋などに行くと可愛い靴下があるけど、15足揃えようとすると店舗に15足も同じ靴下があることはまれなので、供給が安定していて家から買い足しに行きやすい無印良品で揃えることにした。

歯磨き用品のコップを何にしようか迷っている

  • 食洗機可能は必要
  • プラスチック(割れない)
  • かけたりなくしたりするのを織り込んで同じ形の製品が手軽に入手できる必要がある
  • スタック可能だとよい
  • 取っ手がついているとなおよい
  • 子供が扱いやすいサイズだとよい

スケーターあたりの食洗機対応にすると、子供向けの図柄が載っていて、交換の部品もたくさんあって、便利そう。スタックできなさそう以外は完璧。 スタックのことを考えると大人の食事用のコップになるが、スタック可能かつ取っ手がついているかつ樹脂製かつ子供が扱いやすいサイズ、あんまりなさそう。 探して買う。

寄付

log4j2の件もあったしApache Software Fundationに寄付をした

今年Ruby Associationに💴し忘れていたのでそちらも申し込みをした

www.ruby.or.jp

るりまのRDファイルをJSONに変換する

前回

bitclust serverコマンドにオプションを追加し、GraphQLの口を作った

https://github.com/hanachin/bitclust/tree/graphql

こう --graphql オプションを渡すとGraphQLが生える

% bundle exec bitclust server --debug --port=4567 --auto --baseurl=http://localhost:4567/ --graphql

GraphiQL

前回のブランチではGraphQLの口を作った。以下のようなファイルを用意してGraphiQL経由で動作が確認できるようになった、べんり

gist.github.com

RDファイルをJSONに変換する

るりまでは RDCompiler を利用してRDファイルをHTMLに変換している。 RDCompilerではパースとHTMLの出力を同時に行っている。 HTMLを出力せずにJSONに変換するため、以下のようなステップで書き換えを行った。

  1. 出力を行う部分を分離する
  2. 出力を行う部分をJSONへの出力で置き換える
  3. GraphQL経由でJSONへの出力を利用可能にする

結果

今日時点での最新コミットだとDocEntryのRDファイルをパースした結果がJSONで取れるようになった🎉

github.com

以下のようなクエリを投げると

query {
  methodDatabase(version: "3.0.0") {
    doc(id: "index") {
      id,
      title,
      body
    }
  }
}

以下のようなレスポンスが返ってくる

{
  "data": {
    "methodDatabase": {
      "doc": {
        "id": "index",
        "title": "オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル",
        "body": [
          {
            "level": 1,
            "name": "ul",
            "children": [
              {
                "level": 1,
                "name": "li",
                "children": [
                  "Ruby オフィシャルサイト ",
                  {
                    "name": "bracket_link",
                    "type": "url",
                    "arg": "https://www.ruby-lang.org/ja/"
                  }
                ]
              },
              {
                "level": 1,
                "name": "li",
                "children": [
                  "開発版対応リファレンス"
                ]
              },
              {
                "level": 1,
                "name": "li",
                "children": [
                  "原著:まつもとゆきひろ"
                ]
              },
              {
                "level": 1,
                "name": "li",
                "children": [
                  "最新版URL: ",
                  {
                    "name": "bracket_link",
                    "type": "url",
                    "arg": "https://www.ruby-lang.org/ja/documentation/"
                  }
                ]
              }
            ]
          },
          {
            "name": "headline",
            "label": "使用上の注意",
            "level": 2,
            "fragment": null
          },
          {
            "name": "paragraph",
            "children": [
              "組込みクラスのリファレンスはほぼ揃っています。標準添付ライブラリのリファレンスは一部未完成です。それ以外のドキュメントについては、まだまだ書き直しが必要です。\n"
            ]
          },
          {
            "name": "headline",
            "label": "目次",
            "level": 2,
            "fragment": null
          },
          {
            "level": 1,
            "name": "ul",
            "children": [
              {
                "level": 1,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/intro"
                  }
                ]
              },
              {
                "level": 1,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/commands"
                  }
                ]
              },
              {
                "level": 1,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/rubycmd"
                  }
                ]
              },
              {
                "level": 1,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/envvars"
                  }
                ]
              }
            ]
          },
          {
            "name": "headline",
            "label": "Ruby 言語仕様",
            "level": 3,
            "fragment": null
          },
          {
            "name": "paragraph",
            "children": [
              "Ruby でのオブジェクト:\n"
            ]
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/object"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/class"
                  }
                ]
              }
            ]
          },
          {
            "name": "paragraph",
            "children": [
              "プロセスの実行:\n"
            ]
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/eval"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/terminate"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/thread"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/safelevel"
                  }
                ]
              }
            ]
          },
          {
            "name": "paragraph",
            "children": [
              "Ruby の文法:\n"
            ]
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/lexical"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/program"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/variables"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/literal"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/operator"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/control"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/call"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/def"
                  }
                ]
              }
            ]
          },
          {
            "name": "paragraph",
            "children": [
              "その他:\n"
            ]
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/m17n"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/regexp"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "spec/lambda_proc"
                  }
                ]
              }
            ]
          },
          {
            "name": "headline",
            "label": "組み込みライブラリ",
            "level": 3,
            "fragment": null
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "lib",
                    "arg": "_builtin"
                  }
                ]
              }
            ]
          },
          {
            "name": "headline",
            "label": "標準添付ライブラリ",
            "level": 3,
            "fragment": null
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "lib",
                    "arg": "/"
                  }
                ]
              }
            ]
          },
          {
            "name": "headline",
            "label": "C API",
            "level": 3,
            "fragment": null
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "f",
                    "arg": "/"
                  }
                ]
              }
            ]
          },
          {
            "name": "headline",
            "label": "その他",
            "level": 3,
            "fragment": null
          },
          {
            "level": 2,
            "name": "ul",
            "children": [
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "news/index"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "pack_template"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "print_format"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "glossary"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "symref"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "marshal_format"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "license"
                  }
                ]
              },
              {
                "level": 2,
                "name": "li",
                "children": [
                  {
                    "name": "bracket_link",
                    "type": "d",
                    "arg": "help"
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  }
}

次試したいこと

ひとまず、ひき続きRDからJSONに変換できる対象を拡大していきたい。 組み込みクラスあたりまでJSONで出せるようになったらフロントエンドの実装をしてみる。

JSONへ変換する試みをしている最中にリスト処理のバグを見つけたので報告した。

github.com

こっちのバグも直しておきたい。(なおGraphQLお試しブランチでは直っている)

るりまのフロントエンドを分離したいなぁ

現状

bitclustのコマンドで静的なHTMLを生成している。 テンプレートがbitclustに内包されており、HTMLの構造についてある程度分離されているが一部のHTMLを生成する部分はRubyで書かれている。

こうしたい

bitclustにGraphQLのインターフェイスをおく。 GraphQL経由で取得した情報をもとに、フロントエンドのツールチェインを利用してHTMLを生成する。

フロントエンドを分離することで、フロントエンドのツールをより手軽に利用できるようにし、マニュアルの使い勝手を向上させる足がかりとしたい。あとフロントエンド得意な人のコントリビュートチャンスを増やしたい。

いま試していること

bitclust serverコマンドにオプションを追加し、GraphQLの口を作った

https://github.com/hanachin/bitclust/tree/graphql

こう --graphql オプションを渡すとGraphQLが生えるので

% bundle exec bitclust server --debug --port=4567 --auto --baseurl=http://localhost:4567/ --graphql

こういう感じで叩くと

% curl -s -X POST -H 'Content-Type: application/json' -d '{"query": "query ListDocs($version: ID!){ methodDatabase(version: $version){encoding,version,docs{id,title}}}","variables":{"version":"3.0.0"}}' http://localhost:4567/graphql

こんな感じで情報が取れる

{
  "data": {
    "methodDatabase": {
      "encoding": "utf-8",
      "version": "3.0.0",
      "docs": [
        {
          "id": "symref",
          "title": "Rubyで使われる記号の意味(正規表現の複雑な記号は除く)"
        },
        {
          "id": "help",
          "title": "このマニュアルのヘルプ"
        },
        {
          "id": "spec.thread",
          "title": "スレッド"
        },
        {
          "id": "news.2_4_0",
          "title": "NEWS for Ruby 2.4.0"
        },
        {
          "id": "platform.index",
          "title": "Ruby が動作するプラットフォーム"
        },
        {
          "id": "news.1=2e8=2e4",
          "title": "ruby 1.8.4 feature"
        },
        {
          "id": "ReFe",
          "title": "ReFe"
        },
        {
          "id": "spec.def",
          "title": "クラス/メソッドの定義"
        },
        {
          "id": "marshal_format",
          "title": "Marshal フォーマット"
        },
        {
          "id": "platform.Win32=2dnative",
          "title": "Win32ネイティブ版"
        },
        {
          "id": "spec.control",
          "title": "制御構造"
        },
        {
          "id": "news.2_7_0",
          "title": "NEWS for Ruby 2.7.0"
        },
        {
          "id": "spec.eval",
          "title": "Ruby プログラムの実行"
        },
        {
          "id": "spec.terminate",
          "title": "終了処理"
        },
        {
          "id": "platform.GNU",
          "title": "GNU"
        },
        {
          "id": "platform.Win32",
          "title": "Win32"
        },
        {
          "id": "glossary",
          "title": "Ruby用語集"
        },
        {
          "id": "news.3_0_0",
          "title": "NEWS for Ruby 3.0.0"
        },
        {
          "id": "news.2_5_0",
          "title": "NEWS for Ruby 2.5.0"
        },
        {
          "id": "index",
          "title": "オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル"
        },
        {
          "id": "platform.Cygwin",
          "title": "Cygwin"
        },
        {
          "id": "news.index",
          "title": "Ruby変更履歴"
        },
        {
          "id": "spec.operator",
          "title": "演算子式"
        },
        {
          "id": "spec.rubycmd",
          "title": "Rubyの起動"
        },
        {
          "id": "spec.safelevel",
          "title": "セキュリティモデル"
        },
        {
          "id": "platform.MinGW",
          "title": "MinGW"
        },
        {
          "id": "platform.Unix",
          "title": "Unix"
        },
        {
          "id": "news.1=2e8=2e1",
          "title": "ruby 1.8.1 feature"
        },
        {
          "id": "spec.m17n",
          "title": "多言語化"
        },
        {
          "id": "spec.regexp",
          "title": "正規表現"
        },
        {
          "id": "platform.mingw32",
          "title": "mingw32"
        },
        {
          "id": "platform.DOSISH=2dsupport",
          "title": "DOSISH 対応"
        },
        {
          "id": "spec.commands",
          "title": "コマンド"
        },
        {
          "id": "spec.variables",
          "title": "変数と定数"
        },
        {
          "id": "pack_template",
          "title": "pack テンプレート文字列"
        },
        {
          "id": "license",
          "title": "配布条件"
        },
        {
          "id": "news.1=2e8=2e0",
          "title": "1.6.8から1.8.0への変更点(まとめ)"
        },
        {
          "id": "platform.mswin32=2dcompat",
          "title": "Win32ネイティブ版Rubyの互換性問題"
        },
        {
          "id": "news.2_0_0",
          "title": "NEWS for Ruby 2.0.0"
        },
        {
          "id": "news.2_6_0",
          "title": "NEWS for Ruby 2.6.0"
        },
        {
          "id": "spec.envvars",
          "title": "環境変数"
        },
        {
          "id": "news.1_9_0",
          "title": "ruby 1.9 feature"
        },
        {
          "id": "manual=2dpage",
          "title": "manual page"
        },
        {
          "id": "spec.lambda_proc",
          "title": "手続きオブジェクトの挙動の詳細"
        },
        {
          "id": "spec.lexical",
          "title": "字句構造"
        },
        {
          "id": "platform.GNUHurd",
          "title": "GNU Hurd"
        },
        {
          "id": "news.2_2_0",
          "title": "NEWS for Ruby 2.2.0"
        },
        {
          "id": "news.1=2e6=2e0",
          "title": "ruby 1.6 feature"
        },
        {
          "id": "news.2_1_0",
          "title": "NEWS for Ruby 2.1.0"
        },
        {
          "id": "spec.literal",
          "title": "リテラル"
        },
        {
          "id": "news.1=2e8=2e2",
          "title": "ruby 1.8.2 feature"
        },
        {
          "id": "platform.MacOSX",
          "title": "Mac OS X"
        },
        {
          "id": "news.2_3_0",
          "title": "NEWS for Ruby 2.3.0"
        },
        {
          "id": "print_format",
          "title": "sprintf フォーマット"
        },
        {
          "id": "platform.mswin32",
          "title": "mswin32"
        },
        {
          "id": "news.1=2e8=2e5",
          "title": "ruby 1.8.5 feature"
        },
        {
          "id": "spec.intro",
          "title": "はじめに"
        },
        {
          "id": "news.1=2e8=2e3",
          "title": "ruby 1.8.3 feature"
        },
        {
          "id": "spec.program",
          "title": "プログラム・文・式"
        },
        {
          "id": "spec.class",
          "title": "クラス"
        },
        {
          "id": "spec.object",
          "title": "オブジェクト"
        },
        {
          "id": "spec.call",
          "title": "メソッド呼び出し(super・ブロック付き・yield)"
        }
      ]
    }
  }
}

次ためすこと

一応口ができたので、現状のるりまが生成するHTMLを模してHTMLを生成できるかやってみる

もう二度とラップトップにミルクティーを飲ませない気持ち2021冬

ラップトップにミルクティーを飲ませたら起動しなくなってしまった、つらい

デスクで飲み物を飲まないとか、水ではないものを飲まないとか、蓋のついたコップを常に使うとかは無理(それを遂行できないことが今回確認できた)なので別の対策をする。

飲み物をこぼしてラップトップが飲んじゃうのは、ラップトップより液体の位置が高いのが原因なので、ラップトップをディスプレイあたりの位置にマウントしてやれば絶対飲めないだろうと思う。

対策としてラップトップの頭を高くしてラップにおかないラップトップにして使う。

マウント探しします。

いいなと思ったらKyashでお金を下さい
20191128011151
GitHubスポンサーも受け付けています
https://github.com/sponsors/hanachin/