見出し画像

Outvokeのことを、なんと説明すればいいだろう

わたくし(cleemy desu wayo)が2023年12月から書いているCC0のライブラリであるOutvoke(アウトヴォーク)について、軽く説明しておくことにする。

今回の記事は、Outvokeのバージョン 0.0.99.20250614 が前提。これが2025年6月27日時点でのOutvoke本体の最新版である。

Outvokeのリポジトリ(プロジェクト)のURLは以下。
https://gitlab.com/cleemy-desu-wayo/outvoke

README 日本語版は以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/blob/main/README.ja.md

Outvoke本体の入手

Outvoke本体の最新版は以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/blob/main/outvoke.rb

この最新版のファイル本体は以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/raw/main/outvoke.rb

Wayback Machine にアーカイブがあったりするかもしれない。
https://web.archive.org/web/20250000000000*/https://gitlab.com/cleemy-desu-wayo/outvoke/-/raw/main/outvoke.rb

2025年6月27日時点での最新版であるバージョン 0.0.99.20250614 へのPermalinkは以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/blob/4688b8d781099af13cacaa5a8d859b12c60c1034/outvoke.rb

このバージョン 0.0.99.20250614 のファイル本体は以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/raw/4688b8d781099af13cacaa5a8d859b12c60c1034/outvoke.rb
よく分からない場合は、とりあえずこれをダウンロードして実行権限を付与すればOK。ファイル1個だけがあればよく、特に設定などは必要ない。

webrickなどのgemは別途インストールする必要はあるかもしれないが、データソース "web-001" を使わないなら特に必要ない。

以下のように実行して、1秒に1行ずつ出力が増えていくなら、とりあえず動作はしている。

$ ./outvoke.rb -e hooksec

上記の「hooksec」は省略形で、省略前は以下。

$ ./outvoke.rb -e 'hook "every-sec"'

ちなみに2025年6月27日時点でのRubyの最新版は 3.4.4。
https://techracho.bpsinc.jp/hachi8833/2025_05_15/150994

Xにポストした解説画像

2025年6月後半に、画像での解説をXにポストした。

すでにAWKを知っている人にとっては、先にこの6枚の解説画像を見てもらうのがいいかもしれない。AWKを知らない人は眺めるだけでいい。

Outvokeでの「イベント情報が詰め込まれているe」について 1of6
Outvokeでの「イベント情報が詰め込まれているe」について 1of6
Outvokeでの「イベント情報が詰め込まれているe」について 2of6
Outvokeでの「イベント情報が詰め込まれているe」について 2of6
Outvokeでの「イベント情報が詰め込まれているe」について 3of6
Outvokeでの「イベント情報が詰め込まれているe」について 3of6
Outvokeでの「イベント情報が詰め込まれているe」について 4of6
Outvokeでの「イベント情報が詰め込まれているe」について 4of6
Outvokeでの「イベント情報が詰め込まれているe」について 5of6
Outvokeでの「イベント情報が詰め込まれているe」について 5of6
Outvokeでの「イベント情報が詰め込まれているe」について 6of6
Outvokeでの「イベント情報が詰め込まれているe」について 6of6

これら6枚の画像では書き忘れたが、e というのは OutvokeEvent クラスのインスタンス。そしてOutvokeEvent クラスは String クラスのサブクラス。

6枚の画像については、Xでのポストは以下。

https://x.com/metanagi/status/1936269998647132210

「イベント情報を詰め込んだe」についての解説画像を作成しときます。
マッチした情報が配列で e.m に入ってたりしてることとか、組み込みみのデータソース "stdin" を使えばAWKライクなことが可能なこととか。
バージョン 0.0.99.20250614 時点の情報
#outvoke

https://x.com/metanagi/status/1936269998647132210

以下は埋め込みによる表示。

https://x.com/metanagi/status/1936619381758525539

Outvokeでの「イベント情報が詰め込まれているe」についての画像での解説、後半の3枚。
hookcc(マルチスレッド)の例と注意点。
バージョン 0.0.99.20250614 時点の情報
#outvoke

https://x.com/metanagi/status/1936619381758525539

以下は埋め込みによる表示。

解説画像からワンライナーなどを抽出

画像として作成してしまったので、コピペで使えるようにワンライナーの箇所などをこちらにも文字情報として掲載しておく。

こういったサンプルコードやサンプルデータなどもすべてCC0。

コピペする時は先頭の「$」に注意してほしい。

■話の前提 (1) seqコマンドで連番の出力が可能(Outvokeとは直接関係ない)

$ seq 105 108

■話の前提 (2) shufコマンドでシャッフルが可能(Outvokeとは直接関係ない)

$ seq 105 108 | shuf

■話の前提 (3) Outvokeにおける「イベント」って?

パターンを評価して、nil や false では「ない」時に発生するものが、イベント

■話の前提 (4) Outvokeによる通常の正規表現マッチ

$ seq 1 40 | ./outvoke.rb -e 'hook("stdin", /3/)'

"stdin" がデータソースの指定で /3/ がパターンの指定

Outvokeには -q オプションもあり、挙動が grep に近づく

■e の使用例 (1) ブロックがある場合、ブロック内では e が使える

$ seq 12085 12088 | ./outvoke.rb -e 'hook("stdin", /0/) { "matched line: #{e}" }'

これはつまり、e はAWKのアクション部における $0 に近い

$ seq 12085 12088 | awk '/0/ { print "matched line: " $0 }'

■e の使用例 (2) ブロック内では、e.m[0] によってマッチした部分文字列を取り出せる

$ seq 12085 12088 | ./outvoke.rb -e 'hook("stdin", /0../) { "matched string: #{e.m[0]}" }'

AWKではちょっと面倒かも

$ seq 12085 12088 | awk 'match($0, /0../) { print "matched string: " substr($0, RSTART, RLENGTH) }'

■e の使用例 (3) AWKではパターン部で正規表現ではなくコードが書けるが、Outvokeでも Regexp ではなく Proc を指定可能

$ seq 12085 12088 | ./outvoke.rb -e 'hook("stdin", ->{ _1.match(/0../) }) { "matched string: #{e.m[0]}" }'

■e の使用例 (4) 正規表現のグルーピング(グループ化)を使った後方参照も可能(AWKではやりにくいかも)

$ seq 105 108 | ./outvoke.rb -e 'hook("stdin", /(.)0(.)/) { e.m }'

ちなみに e.m は配列

■e の使用例 (5) データソース "stdin" を指定する時は、「hookstd」というシュガー的なもの(省略形)が使える

$ seq 105 108 | ./outvoke.rb -e 'hookstd(/(.)0(.)/) { e.m }'

■e の使用例 (6) Outvokeは複数のデータソースを指定可能

$ LC_ALL=C date | ./outvoke.rb -e 'hook("stdin") { e.gsub("0", "o") } ; hook("every-sec") { e.gsub("0", "@") }'

■e の使用例 (7) 複数のデータソース指定では、こんなことも可能

$ LC_ALL=C date | ./outvoke.rb -e 'hook(/stdin|every-sec/) { e.gsub("0", "x") }'

■hookcc の例 (1) 後ろの行を先に出してみる

$ seq 12087 12091 | ./outvoke.rb -e 'hookcc("stdin", /08/) {|e| sleep 3 ; "matched line: #{e}" } ; hookstd(/09/)'

■hookcc の例 (2) 4chanが産んだ画期的(?)なアルゴリズムのスリープソートを試す

$ seq 1 5 | shuf | ./outvoke.rb -e 'hookcc("stdin") {|e| sleep e.to_i }'

■hookcc の例 (3) yt-dlp を使った並行処理

以下のような hoge.txt があるとして

$ cat hoge.txt
[show-me-first] hello.
this is green? https://www.youtube.com/watch?v=4Sc81yxo600
red? v=4Sc81yxo600
https://www.youtube.com/watch?v=apBWI6xrbLY good
[show-me-first] ruby test https://www.youtube.com/watch?v=u1O9YuXNbLs ruby test
aaa
duvet https://www.youtube.com/watch?v=KQiz9Wjwh-I
I'm in Okinawa https://www.youtube.com/watch?v=7Awc6qUni44
[show-me-first] this is last line in this file. can you read this?

yt-dlpを並行処理(同時実行)して動画タイトル取得

$ cat hoge.txt | ./outvoke.rb -e 'hookcc("stdin", /youtube\.com\/watch\?v=([-_a-zA-Z0-9]*)/) {|e| t = IO.popen(["./yt-dlp_linux", "-q", "--get-title", "https://www.youtube.com/watch?v=#{e.m[1]}", :err=>"/dev/null"]).each_line.first ; "videoid: #{e.m[1]} title: #{t}" } ; hookstd(/^\[show-me-first\]/)'

さすがにワンライナーとしては長いので、ファイルにしてみる

# yt-dlp test

using OutvokeDSL

hookcc "stdin", /youtube\.com\/watch\?v=([-_a-zA-Z0-9]*)/ do |e|
  t = IO.popen(["./yt-dlp_linux",
                "-q",
                "--get-title",
                "https://www.youtube.com/watch?v=#{e.m[1]}",
                :err=>"/dev/null"
               ]).each_line.first
  "videoid: #{e.m[1]} title: #{t}"
end

hookstd /^\[show-me-first\]/

上記の内容を hoge.rb として保存した場合、以下で同じことを実行できる

$ cat hoge.txt | ./outvoke.rb hoge.rb

セキュリティ上の理由により、IO.popen や Kernel.#spawn に渡す引数ではOSコマンド全体が単一の文字列にならないよう注意

以下は3秒おきに yt-dlp を実行する良心設計の hoge2.rb

# yt-dlp test

using OutvokeDSL

videocnt = 0
mutex = Mutex.new

hookcc "stdin", /youtube\.com\/watch\?v=([-_a-zA-Z0-9]*)/ do |e|

  mutex.synchronize do
    videocnt += 1
  end

  sleep 3 * videocnt

  t = IO.popen(["./yt-dlp_linux",
                "-q",
                "--get-title",
                "https://www.youtube.com/watch?v=#{e.m[1]}",
                :err=>"/dev/null"
               ]).each_line.first

  "videoid: #{e.m[1]} title: #{t}"
end

hookstd /^\[show-me-first\]/

hookcc の中での sleep はいろいろ便利

■注意点 (1) hookcc は e をディープコピーしている

以下はエラーになる、e.m[0] が MatchData オブジェクトだから

$ seq 105 108 | ./outvoke.rb -e 'hookcc("stdin", ->{ _1.match(/(.)0(.)/) }) {|e| "matched data: #{e.m}" }'

(※画像の説明では「e.m が MatchData オブジェクトだから」と書いてしまったけど、これは不正確。この周辺は近いうちに微妙な仕様変更あるかも)

以下のように Object#to_a しとくと、ディープコピーに耐えるものになる

$ seq 105 108 | ./outvoke.rb -e 'hookcc("stdin", ->{ _1.match(/(.)0(.)/).to_a }) {|e| "matched data: #{e.m}" }'

現状(バージョン 0.0.99.20250614)では、上記の例では |e| を省くと Object#to_a しなくてもエラーは出なくなる、ただしマルチスレッドとしては潜在的にはまずい(次節を参照)

■注意点 (2) hookcc 時に |e| しないとまずいことが分かる短い例

$ seq 12085 12088 | ./outvoke.rb -e 'hookcc("stdin", /0../) { sleep 0.2 ; e.m[0] } ; hookstd(/.$/) { nil }'

「085」などが出力されてほしいのに、後ろの hookstd のマッチの結果が出てしまってる

以下のように |e| があるならOK

$ seq 12085 12088 | ./outvoke.rb -e 'hookcc("stdin", /0../) {|e| sleep 0.2 ; e.m[0] } ; hookstd(/.$/) { nil }'

どういうつもりでOutvokeを書き始めたのか

そろそろOutvokeのチュートリアル的な記事を書いたほうがいいかもしれないと思いつつ、時間が経ってしまった。

今年(2025年)は互換性を破壊するような変更をいろいろと加える可能性があるから、そのあたりのことが固まるまで書かないほうがいいかもしれないというのもあった。

現状のリポジトリ内の README では、組み込みのデータソースが "every-sec" と "vrchat-001" の2つしかなかった最初期のころのOutvokeが濃厚に反映されている。そして、Outvokeの全体像についてはすでに把握している人向けになっているかもしれない。

ここでいう「データソース」というのは、Outvoke固有の用語である。

ちなみに2025年6月27日時点での README 日本語版の最新版(日本時間で2024年12月21日早朝更新)へのPermalinkは以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/blob/8d55ba94f943e9d5ac57ceb623d9fa3366e93d62/README.ja.md

Outvokeについて、そもそもどういうつもりで書き始めたのかを軽く書いておこうと思う。

ここからはプログラミング初心者向けの解説ではないので注意。

また、Linuxが前提であることにも注意。

まずは "stdin" について。

前掲の6枚の画像では、組み込みのデータソースとして "stdin" を利用したものを中心に解説した。"stdin" を中心にすると、AWKと比較しながら説明することが出来るのはメリットかもしれない。

"stdin" を組み込みのデータソースとして用意するのはバージョン 0.2 からでいいかもしれないと思ったけど、解説用としては "stdin" は実に便利だということに気づいた。

ただし、こんな風に "stdin" で延々と解説をやってしまうと、Outvokeというのは「気軽にマルチスレッド化できるAWK」のようなものでしかないということになってしまうかもしれない。

まあそれはそれで間違いではないのだが、作者としては、標準入力以外の複数のデータソースを同時に扱ったり、使う人が自分でデータソースを用意したりする時にこそ威力を発揮するはずであるというつもりで書いているわけだ。

「自分でデータソースを用意」というのは、OutvokeDataSource のサブクラスを自分で定義しておくということである。

データソースの役割としては、ストリーム的でないものについてもストリーム的に扱えるように落とし込むというのが重要である。

ちなみに、Outvokeを書き始めた2023年12月時点ではわたくしはAWKを意識していたわけではなく、表記の面でSinatraのように出来るかどうかが重要だった。

内部DSLとしてのSinatraを面白いと思えなかったり、「こんな風に書きたくない」と思ってしまう人には、おそらくOutvokeは向いていない。

言語あるいはアーキテクチャという観点では、オブジェクトが中心になるのではなくメッセージが中心になるというのも意識していて、あとになってみるとこれはRPCに近いといえる。

RPCとの比較においては、前述の「ストリーム的でないものもストリーム的に扱える」というのは重要だ。

RPCの場合は通常はメッセージを送信する側のアプリケーションがRPCのプロトコルを強く意識するわけだが、Outvokeではそうとは限らない。例えば、最初期のOutvokeからあった組み込みのデータソース "vrchat-001" では、VRChatクライアントによるただのログの書き込みがいつの間にかメッセージ送信だったことにされてしまうというのがポイントだ。

わたくしがVRChatを始めた2023年11月時点ではすでにVRChatはOSCに対応していたし、本当にログファイルを見るだけで実用的になるのかどうかは実際に自分でしばらく運用してみないと確信が持てないものだった。

VRChatでは、自分がいるインスタンスに誰かが入室(join)してきた時と退室(leave)した時にログが出力される。だから入退室履歴というのは良い題材だった。

わたくしとしては、たまに数秒遅れることがある、みたいな感じでもまったくかまわなかった。でもわたくしの低スペックPCでもそういうことはほぼまったく起こらなかった。

最近よく「ニアリアルタイム」という言い方がされるらしいが、わたくしはこの「ニアリアルタイム」を再発見したともいえるかもしれない。

ちなみにVRChatでの入退室履歴のシンプルなワンライナーは以下である。

$ ./outvoke.rb -e 'hook "vrchat-001", /(onplayerjoined|onplayerleft) /i'

VRChatを起動してから上記を実行してもかまわないし、先に上記を実行してからVRChatを起動してもかまわない。ログファイルの場所がいつの間にか変わっていないか探ったりとか、そういう面倒なことを自動でやるのもデータソースの役割だ。

「Visitors Information Board」のようなアセットが設置されているワールドでは、以下のようにしないと余計な情報を拾ってしまうかもしれない。

$ ./outvoke.rb -e 'hook "vrchat-001", /\[Behaviour\] (onplayerjoined|onplayerleft) /i'

こういうワンライナーを起動させたままにしておけば、自分がいるインスタンスで動きがあった時に次々と新しい出力があるようになるわけだ。

ちなみに「Visitors Information Board」が設置されているワールドの例として「銭湯(Bathhouse)」[vrcw.net] がある。

Outvookeを利用した入退室履歴として、もう少し凝ったサンプルプログラムが samples/vrchat_join_log3.rb である。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/blob/main/samples/vrchat_join_log3.rb

ファイル本体は以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/raw/main/samples/vrchat_join_log3.rb

outvoke.rb と vrchat_join_log3.rb が同じディレクトリにあるなら、以下で実行できる。

$ ./outvoke.rb vrchat_join_log3.rb

tee コマンドと組み合わせると便利である。

$ ./outvoke.rb vrchat_join_log3.rb | tee log/join_history_$(date "+%Y-%m-%d_%H-%M-%S").txt

VRChatではワールドによってログファイルに書かれるものが異なる。

比較的どのワールドでも拾いやすいものを以下に列挙しておく。

  • 入退室の情報

  • 自分のカメラやF12で撮影したものの情報

  • 自分がpickupしたものの情報

  • 動画の再生開始時点での動画の情報

ワールド固有の例を一つだけ挙げておくと、2025年6月27日時点でのJPST(Japan Street)[vrcw.net] では、駅周辺にある2箇所の弾き語りポイントに誰かがいる時にそのユーザー名が分かる。

以下を起動した状態で弾き語りポイントに自分で入ってみて、最長で10秒待つと自分のユーザー名を含む出力があるはずだ。

$ ./outvoke.rb -e 'hook "vrchat-001", /boost/i'

これらはあくまでも、自分がいるインスタンスについての情報である。

なお、2025年6月27日時点でのJPSTのワールド名は「Japan Street 0․442」である。

ちなみにOutvokeでは、以下のように hook ではなく hookft を使うことにより、Outvoke起動時に過去にさかのぼって検索する。

$ ./outvoke.rb -e 'hookft "vrchat-001", /\[Behaviour\] (onplayerjoined|onplayerleft) /i'

「ft」は「first time」のつもりだ。また、複数のログファイルにまたがってさかのぼることはしない。

組み込みのデータソースとしては、OSCを前提にしたVRChat用インターフェースを用意する日は来ない可能性がある。あくまでもログファイルが重要である。

Outvokeは教育用ソフトウェアとしての側面も意識している。ログを見るだけというのは、モックアップをつくりやすい。ソースコードが公開されていないVRchatクライアントのような巨大で複雑なアプリケーションのモックアップを自分で作成してみるのも教育用としていいかもしれないと思っている。

そもそもモックアップってどういうこと?ということを体験しやすいわけだ。

アプリケーション同士の連携だけに着目するなら、外見をそっくりにする必要はないし、もしかするとGUI的要素を持つ必要すらないかもしれない。

教育用とはいっても、現状のOutvoke本体のコードについては慌てて書いた部分が多数残っているため、反面教師にしかならないかもしれないことには注意してほしい。

わたくしはOutvokeのようなものを書くつもりでVRChatを始めたわけではない。VRChat自体は、Linuxでも動作するメタバースの現状が知りたくて始めただけだ。Outvokeについても最初はほんのちょっとした遊びのつもりだった。

VRChatクライアントはリアルタイムでいろんな情報がログファイルに書き出されるし、OSCにも対応している。Spatial.io のようなブラウザベースのメタバースの場合は、Outvokeとの連携は難しいかもしれない。ブラウザベースであっても、OSC over WebSocket のようなものに対応してくれるのであれば、Outvokeとの連携が容易になるかもしれない。

ここで、Outvokeにおけるデータソースという存在についても軽く説明しておく。

Outvokeに最初期からあった組み込みのデータソース "vrchat-001" と "every-sec" は、ともに元のデータがストリーム的でない。

"vrchat-001" では、通常はログというものは追記しかされないはずだという前提で、ストリーム的に扱っている。tail -f と発想は近く、トリッキーというわけではない。

"every-sec" の場合は、時間そのものには元からデータ自体が存在していないため、若干おかしなことが起こっている。ストリームの捏造ねつぞうとすらいえる。

Outvokeにおいては、「ソース」と「オリジン」は違うといえる。"vrchat-001" はオリジンがファイルとして実在しているが、"every-sec" ではオリジンに実体がない。

いずれOutvoke固有の用語も整理する必要があるだろう。

ちなみにOutvokeの最初の公開バージョン(バージョン 0.0.99.20231231)は以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/blob/35a762561e9a1d21a786e3f6f936e644f2f18ba8/outvoke.rb

今は1,200行を超えてしまったが、当初は400行にも満たないものだった。

このファイル本体は以下。
https://gitlab.com/cleemy-desu-wayo/outvoke/-/raw/35a762561e9a1d21a786e3f6f936e644f2f18ba8/outvoke.rb

データソース "stdin" については、バージョン 0.0.99.20240809 から登場した機能だ。標準入力の場合は最初からストリームなので、データソースとしての面白味はさほどない。

標準入力なのだからAWK的になるのもまあ当然という感じだ。

当然といえば当然のはずなのだが、"stdin" を用意すればAWK的になるというのは、Outvokeを書き始めてからかなり時間が経ってから気づいた。

なお、自前のデータソースについては、設定ファイルに分離しておくことが可能だ。

前掲の6枚の画像の中でも書いたが、Outvokeは実行時に先にカレントディレクトリの outvoke.conf.rb を読み込んで実行する。だから、このファイルの中でいろんなクラスやトップレベルのメソッド(mainオブジェクトのメソッド)を定義しておくことが可能である。

プラグイン風味になるよう、特定のディレクトリの .rb をすべて読み込んだりするように変更する可能性もある。

本当はこの「ああこんなに簡単にデータソースを定義できるのか」というのを早く解説したほうがいいのかもしれない。

フレームワークとしてのOutvoke

Outvokeはフレームワークのつもりでもある。

Rubyでフレームワークといえば Ruby on Rails が非常に有名だ。

Railsは巨大でモノリシックなアプリケーションの構築に向かわせるけど、Outvokeはまったく逆であり、アプリケーションの分割をうながす。

徹底的に分割していくとメッセージのルーティングしかしていないような状態になるはずで、Railsのようなフレームワークとはかなり違う。

前述のように、Outvokeでは自前で用意したデータソースこそが重要な要素にはなるのだが、分割を促進していくとデータソースを用意する必要すらなくなる。ストリーム的でないものをストリーム的にする、という部分は完全に別のアプリケーションにしてしまってもかまわない。

当然ながら、別のアプリケーションなのだからその部分についてはRubyで書かれている必要もない。

そういうことのために "auxin" というデータソースを用意する予定だ。この "auxin" の利用によって、FIFO(名前付きパイプ)などでのやり取りが可能になる。

現状では "auxin:fifo:1" なんてデータソースを組み込みで用意していたりするけど、これは実験的なものであり、仕様が固まっていないので注意。

分割ということについては、これから書こうとしているシステムで最初から分割を前提にするというだけではなく、既存の巨大なアプリケーションを大きなシステムの一部として取り込むようなことがやりやすくなる。

この「既存の巨大なアプリケーション」というのは、GUIアプリかもしれないし、Railsアプリかもしれない。VRChatクライアントのようなものかもしれない。あるいは大昔にCOBOLで構築されて化石のようになり、現生人類には理解できなくなったシステムかもしれない。

OutvokeではRailsのような「レール」は用意されていない。そうであるがゆえに、巨大でモノリシックなアプリケーションをOutvokeを利用して書くことも可能ではある。いちおう、理屈のうえでは。

最近知ったことと、今後のこと

わたくしは2024年12月になってからFluentd(フルーエントディー)の存在を知った。そしてこのFluentdを知ると同時に「ニアリアルタイム」という言い方が流行っていることも知った。

ログの中身をニアリアルタイムで監視してアクションを起こす、という用途ではFluentdは重要な先例かもしれない。

2016年時点ですでに以下のような記事があったりもする。

Fluentdによってあらかじめ情報を絞り込んでからOutvokeに流し込む、というような使い方もおそらく可能だろう。Outvokeは大量のデータを扱うことは想定していない。

なお、わたくしは2025年6月時点でまだFluentdを実際に試してはいない。

Outvoke本体については、前述のように今年(2025年)のうちに互換性を破壊する変更(breaking change)が何度かあるかもしれない。

もしかしたら、近いうちに "vrchat-001" は "vrc:log:1" のような名称になるかもしれない。

慌てて解説記事を書いてしまうのはよくないかもしれないと思うのは、こういうことがまだ固まっていないからだ。

いったんバージョン 0.1 をリリースしたら、「0.1.x」というバージョンのものは 0.1 と互換性を持たせるつもりではある。

ところで、最近はAIの性能が向上している。でもバージョン 0.1 をリリースするまでは、AIを使わずに書く予定だ。助言的なことも含めて、ほぼ完全にAIの関与なしにバージョン 0.1 まで持っていくつもりだ。

バージョン 0.1 に関しては、サンプルコードや解説のようなものについても、AIに生成させたものは使わない予定だ。ただし README などの英語版作成については例外である。翻訳における様々な段階でAIを使うことになると思う。

また、わたくしが書いた解説などが現状のAIにも理解できるものになっているかどうかのチェックのためにAIを使うこともあるかもしれない。

わたくしでない誰かがAIを使って見つけたバグをわたくしに指摘してくれるのはいつでも大歓迎である。AIを使って見つけた解説部分の誤字脱字や誤訳などの指摘も、もちろん大歓迎。

ハッシュタグ #outvoke を使ってもらえたら、そのうち見るかもしれないし、見ないかもしれない。
https://note.com/hashtag/outvoke
https://x.com/hashtag/outvoke

目立ちたくない人は、「お題箱」から匿名で送ってもらってもいい。

解説は書こうと思えばいくらでも書けてしまうので、このへんにしておく。

もしバージョン 0.1 を無事に公開することができたら、もう少しまともな解説記事を書く予定だ。

いいなと思ったら応援しよう!

ピックアップされています

No space left on my brain

  • 18本

コメント

ログイン または 会員登録 するとコメントできます。
note会員1000万人突破記念 1000万ポイントみんなで山分け祭 エントリー7/8(火)まで
Outvokeのことを、なんと説明すればいいだろう|cleemy desu wayo
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1