hkoba blog

プログラマーです。プログラミング言語ミーハーです。ツッコミ歓迎です。よろしくどうぞ(能代口調)

Cのマクロの Rust 化 - libperl-rs 現状報告

要約:(XS も含めて)Rust と Perl の相性が良くなったよ!

例えば perlxstut の例2, is_even() が、 libperl-rs でこう書けるようになりました:

use libperl_rs::{xs_boot, xs_sub, IV};

/// `Mytest::is_even($n)` — returns true if `$n` is even.
/// (perlxstut EXAMPLE 2.)
#[xs_sub]
fn is_even(n: IV) -> bool {
    n % 2 == 0
}

xs_boot! {
    package = "Mytest";
    subs = [is_even];
}

どんな問題が有って、どうやって改善したか

Perl の API を Rust から叩くためのライブラリ、 libperl-rs というものを作っています。 これは Rust の bindgen (C のヘッダーから Rust の宣言を自動的に生成するもの)を利用して作ってきました。 これだけでもある程度は役に立つのですが、大きな問題が残っていました。それが C のマクロ関数です。

Perl インタープリターの内部構造は、Perl のバージョンの進化に伴って変化してきました。 そのバージョンごとの差異を吸収するために、Perl の API は大量の C マクロ関数を使って定義されています。 また、スレッド対応の有無の抽象化も C マクロ関数が担っています。

ところが Rust の bindgen は Cのマクロ関数を一切無視します。(static inline 関数も無視します)。 このため、Perl の API で定義された抽象化の仕組みが、libperl-rs 側では一切利用できない状況でした。

例えば昨年末の記事(Rust の libperl-sys で XS を書いてみた - hkoba blog)の時点の libperl-rs では、最初に挙げた is_even() ですら この長さでした。

fn is_even(my_perl: &mut PerlInterpreter, cv: *mut CV) -> () {
    // dSP
    let sp = my_perl.Istack_sp;

    // dAXMARK
    let mut ax: Stack_off_t = unsafe {*my_perl.Imarkstack_ptr};
    my_perl.Imarkstack_ptr = unsafe {my_perl.Imarkstack_ptr.sub(1)};

    // POPMARK
    let mark = unsafe {my_perl.Istack_base.add(ax as usize)};
    ax = ax+1;

    // dITEMS
    let items = unsafe {sp.offset_from(mark)};
    if items != 1 {
        let msg = "input";
        unsafe {Perl_croak_xs_usage(cv, msg.as_bytes().as_ptr() as *const i8)};
    }

    // int     input = (int)SvIV(ST(0))
    let src = unsafe {*my_perl.Istack_base.add((ax + 0) as usize)};
    let input = SvIV(my_perl, src);

    let RETVAL = (input % 2) == 0;
    println!("input {} RETVAL {}", input, RETVAL);

    let targ = unsafe {Perl_sv_newmortal(my_perl)};
    
    // PUSHi((IV)RETVAL);
    unsafe {
        Perl_sv_setiv(my_perl, targ, RETVAL as i64)
    };

    unsafe {*sp = targ};

    let off = 1;
    my_perl.Istack_sp = unsafe {my_perl.Istack_base.add((ax + (off - 1)).try_into().unwrap())};

    return ()
}

#[unsafe(no_mangle)]
pub extern "C" fn boot_Mytest(my_perl_ptr: *mut PerlInterpreter, _cv: *mut CV) -> () {

    if my_perl_ptr.is_null() {
        panic!()
    }

    static NAME1: &CStr = unsafe {
        CStr::from_bytes_with_nul_unchecked(b"Mytest::is_even\0")
    };
    unsafe {
        Perl_newXS_deffile(my_perl_ptr, NAME1.as_ptr(), Some(is_even_C))
    };

    unsafe {
        Perl_xs_boot_epilog(my_perl_ptr, 1);
    };
}

この問題を解決するために Claude Code に作成させたのが libperl-macrogen です。 これは Perl の API で定義された C ヘッダーに特化した、C のマクロ(と inline)関数から Rust の関数を生成するトランスパイラーです。

Claude Code (を始めとした、コーディングエージェント)がプログラミング言語の処理に長けていることは、昨年に Claude Code を触っていた言語好きのプログラマーにはよく知られていることです。そこで私は既存のCコンパイラー OSS である TinyCC のプリプロセッサーと意味解析部分を参考にして、Perl の API に特化した専用のトランスパイラーを作成するように Claude Code に指示することを思いつきました。コーディングエージェントは体力おばけなので、人力では根気の続かないタスクも任せられると考えました。

オリジナルのライセンスを尊重するため、このトランスパイラー部分だけは別プロジェクトとしてプロジェクトを開始しました。

掛かった時間

昨年の冬休みにプロジェクトを開始して、すぐに出来上がるかと思いましたが…結局リリースまで4ヶ月を要しました。

macrogen の CC usage

libperl-sys との統合の CC usage

libperl-rs をどう育てていくかはまだ迷い中です。不足している機能もたくさん有るはず…ご意見いただければ嬉しいです。

ここまで読んでくださり、ありがとうございました!

エディタだけOOPのススメ - Not everything has to be an object.

(職場の同僚に OOP の使いどころを解説するための資料、のつもり)

(人が使うための)全てのプログラムは、大体、エディタである(とみなせる)

プログラムは、大きく荒く捉えれば、ユーザーが扱いたい(どこかに保存された)データをユーザーへ表示して、それを望みの形へ書き換え(て、それをどこかに保存す)るためのものと捉えることが出来る。それは要するにエディタである。(エディタには単なるビューワーも含むとする)

画面の有無は問わないので、例えば以下のような見方が可能である

  • sed はテキスト・ファイルストリームに対するエディタである
  • sh/bash/zsh はファイルシステムに対するエディタである
  • sqlite は sqliteデータベースファイルに対するエディタである
  • 電卓はレジスタに対するエディタである

またこのとき、編集(や単なる表示)の対象となっているものは、状態 (必要なら書き換えの対象となるもの)と捉えるのが、素直だろう。

(余談ですが、自分はプログラミングに対するこの考え方を 「エディタ指向プログラミング」 と呼んでます)

もちろん例外として、単にcpuをぶん回して排熱を作るためのプログラムとか、暗号通貨で金儲けとかもある。けどそれは人が直接使うソフトウェアとは位置づけない、そんな考え方。

状態の更新は、プログラムの理解を難しくする

更新可能な状態が(一般的に)なぜ悪とされることが多いか

プログラム(の正しさ)は論理の集まり(によってしか保証できない、確信できないもの)であり、その論理を記述する式の要素が 勝手に変化 すると論理が成り立たなくなるから

例えば

X= A and B and not(C) 

みたいな論理的記述を考える時に、考える途中で A の値が変わることを許容してしまうと、もはやこの記述は、思考を整理する道具としては役立たずになってしまう。

(値の時間変化を扱うための軽めの論理が一般まで普及すれば、このあたりの事情は変わりうるとして)

なら、オブジェクトはエディタに限って使えば良いのでは?

オブジェクトは、状態の 編集・作用 をカプセル化するためのもの、と捉えて

編集に関わらないものは、全て不変なデータ構造で取り扱うことにして。(細かいオブジェクトは、作らない)

エディタだから、

  • 編集バッファを持って良い
  • オプションが有っても良い
  • キャッシュを持っていても良い
  • カーソル的な、編集文脈のようなものも、本当に必要状況でなら、あって良い

みたいな…

バックエンドサーバー的なものも、全部この考え方で良いのでは、と。

この記事の背景・文脈

ツイッタで OOP の話題が出てたので、つい乗っかりたくなってしまったのです…

謹賀新年/2026目標

あけましておめでとうございます

昨年仲良くして下さった皆様、ありがとうございました。

また本年もよろしくお願いいたします。

昨年の振り返り、良かったこと

  • 仕事

    • ずっと趣味で作ってきたyatt-js の clasp アダプターを GAS の Web UI 作成用に業務で実戦投入できたこと…(とはいえ、他の人に勧められるレベルでは全く無いですし、clasp2.5 用なので clasp3 移行のためにアダプターを丸々作り直す予定…無いよりはマシレベル)

    • 社内の教育プロジェクトみたいなのが程良い具合に同僚にお任せできたことで、これまで教育から漏れてた方にも教育の機会を作れるようになったこと、ありがたや…

    • 社内の有志に直接 GCP を触ってもらう手ほどきを始められたこと

    • IAP(Identity-Aware Proxy) 越しでも gitlab の lfs の設定を有効に出来たこと…これで応用範囲がぐっと広がる!

  • 個人

    • 宮崎のプログラマー系勉強会に参加できたこと。友達欲しい〜!

    • 高千穂峡の推しの子イベント見に行ったり、日南のモアイ像を見に行ったり、都井岬の野生馬を見に行ったり、新田原基地祭で F35B見たり出来たこと

    • SQL::Concat の overload を実装して、やっと理想の便利さを実現できたこと…さっさとやっときゃよかった

    • gugod 氏に教えてもらえたおかげで自分の CPAN モジュールの coveralls を復活出来たこと。App::Yath 便利

    • YAPC::Fukuoka 2025 で OO Modulino の LT 出来たこと、伝わった人がいると実感が得られたこと

    • Claude Code で Perl もまだまだ戦えそう&静的解析の重要性が更に増したと分かったこと

昨年の反省点

  • 部屋がどんどん散らかった…亡き父の部屋まで荷物を押し付けてる状況は、本当は何とかしたい…

今年の目標

  • Rust + libperl という枠組みを、もう少し一般向けに使ってもらえるレベルに仕上げる

  • オレオレ言語・オレオレUI作りも、Claude Code 使ってもっと前倒ししたいな…

あと、艦これアーケードは(週に一度しか遊べてないけど)サ終の日まで走り続けたい…

Rust の libperl-sys で XS を書いてみた

この記事は Perl Advent Calendar 2025 の21日目です。(穴埋め記事だよ!)


Perl5 のランタイムライブラリである libperl を Rust から呼ぶための、 libperl-sys という crate があります。(README すら書いてなくてごめんなさい)

今の libperl-sys は生の libperl の関数群を rust から触るためだけのものなので、Perl5 のバージョン間の互換性を維持するためのプリプロセッサマクロが欠けています。このため、Perl5 のバージョンに依存しないコードを書くには #[cfg(perlapi_ver$ver)] で条件コンパイルを駆使する必要があります。残念ながら、一般向けとは言い難い状況です。(この問題については、目下実験が進行中です)

ですが、逆に言えば、Perl5 の中身を触ることに躊躇しない人にとっては、既に Rust から Perl を触るための道具は揃っているとも言えるのでは無いでしょうか??(発狂)

というわけで、XS のチュートリアルの is_even を Rust に移植してみたらこんな感じになりました。

github.com

usemultiplicity=define 限定の例だし、xsubpp とプリプロセッサマクロで隠されていた部分を全部自分で書く必要があるし、何より unsafe だらけですが、動いてる、ように見えます。(間違ってたらごめんなさい><)

fn is_even(my_perl: &mut PerlInterpreter, cv: *mut CV) -> () {
    // dSP
    let sp = my_perl.Istack_sp;

    // dAXMARK
    let mut ax: Stack_off_t = unsafe {*my_perl.Imarkstack_ptr};
    my_perl.Imarkstack_ptr = unsafe {my_perl.Imarkstack_ptr.sub(1)};

    // POPMARK
    let mark = unsafe {my_perl.Istack_base.add(ax as usize)};
    ax = ax+1;

    // dITEMS
    let items = unsafe {sp.offset_from(mark)};
    if items != 1 {
        let msg = "input";
        unsafe {Perl_croak_xs_usage(cv, msg.as_bytes().as_ptr() as *const i8)};
    }

    // int     input = (int)SvIV(ST(0))
    let src = unsafe {*my_perl.Istack_base.add((ax + 0) as usize)};
    let input = SvIV(my_perl, src);

    let RETVAL = (input % 2) == 0;
    println!("input {} RETVAL {}", input, RETVAL);

    let targ = unsafe {Perl_sv_newmortal(my_perl)};
    
    // PUSHi((IV)RETVAL);
    unsafe {
        Perl_sv_setiv(my_perl, targ, RETVAL as i64)
    };

    unsafe {*sp = targ};

    let off = 1;
    my_perl.Istack_sp = unsafe {my_perl.Istack_base.add((ax + (off - 1)).try_into().unwrap())};

    return ()
}

Claude Code に Devel::Cover を解読してもらったらこんな感じ

この記事は Perl Advent Calendar 2025 の20日目です。(穴埋め記事だよ!)


Devel::Cover は Perl の実行の様子を記録して解析するためのパッケージです。典型的にはテストのカバレッジ(テスト漏れがないかを調べる)ために使われます。詳しくは →こちらの記事 を参照して下さい。

この Devel::Cover には Perl のプログラムの真理値表を生成する機能があります。私は以前から、この機能をカバレッジとは関係なしに、任意のプログラムに対して適用できるように抽出できないか…と考えていました。で、やってみた結果、こんな対話になりました。とくとご覧あれ…

hkoba.github.io

Claude Code は OO Modulino (オゥオゥ・モジュリーノ)も理解してくれる、ぽい!

この記事は Perl Advent Calendar 2025 の2日目です。


それは6月の初旬、Claude Code で Perl がどこまで戦えるか試していた頃のこと…

期待に近いコードが出てきて、さあ試そう!という時の Claude と私のやり取りをご紹介します>


🤖 (Claude) entity補完の実装が完了しました。次にテストを追加します。

🤖 (Claude) entity補完のテストを追加します。

# Entity completion tests
my $inspector;
eval {
  $inspector = YATT::Lite::Inspector->new(dir => $dir);
};
# Test entity macro completion
{
  my @items = $inspector->complete_entities("html/index.yatt", "yatt", "", 0);
  my @macros = grep { $_->{detail} =~ /entity macro/ } @items;
  ok(@macros > 0, "Should have entity macros");
  
  my ($if_macro) = grep { $_->{label} eq 'if' } @macros;
  ok($if_macro, "Should find 'if' entity macro");
  is($if_macro->{detail}, "entity macro yatt:if", "if entity macro detail should be correct");
}
...

AIに最初からテストファイルを書かれても、あまり嬉しくない

  • そもそもテストコードは 読みやすいとは、言いづらい
    • テストコードをさっと読んだだけでは、本当に望みの挙動になっているか、確信が持てない。
  • テストコードを実行しても、このテストが成功したか失敗したかしか分からない
    • AI に誤魔化されているかもしれない。
    • 自分で色々パラメータを変えて試したい。

と思ったので、次のような指示を出しました。

👤 User(hkoba) テストファイルを更新する前に、コマンド行からの同じ意味のテストを行うようにして下さい。

OO Modulino を教えてみた

それに対して Claude は、テスト用のコマンド・ファイルを実装しようとしはじめました。

🤖 Claude コマンドラインからentity補完をテストしましょう。まず、テスト用のコマンドを実装する必要があります。

しかし、私がこの機能の手触りを試したい だけなのに、使い捨てのファイルを増やされても後で手間が増える…ので、 ここは OO Modulino として CLI から直接実行してもらうよう、指示してみました。(読みやすさのために改行を入れています)

👤 User Inspector.pm は modulino なので、メソッドをCLI から試す際にコマンドを実装する必要はありません。このようにして下さい>

./Lite/Inspector.pm --dir=$PWD/samples/basic/1 \
   complete_entities html/foobar.yatt yatt '' 15

Claude の反応や、いかに…

🤖 Claude なるほど、modulinoとして直接メソッドを呼び出せるのですね。コマンドラインからentity補完をテストしてみます。

🤖 Claude tool_use: Bash Test entity completion from command line

./Lite/Inspector.pm --dir=$PWD/samples/basic/1 complete_entities html/foobar.yatt yatt '' 15

tool_result

{"detail":"entity macro yatt:not","documentation":"Built-in entity macro","kind":12,"label":"not"}
{"detail":"entity macro yatt:undef","documentation":"Built-in entity macro","kind":12,"label":"undef"}
...
{"detail":"entity macro yatt:dispatch_one","documentation":"Built-in entity macro","kind":12,"label":"dispatch_one"}
{"detail":"var a: text","kind":13,"label":"a"}
{"detail":"var body: code","kind":13,"label":"body"}
...

🤖 Claude 良いですね!entity補完が動作しています。行15にあるfoo widgetの引数である

a と body が変数として認識されています。

次に、prefix付きで試してみましょう:

ななんと、全て理解した返答をしてくる上に、早速応用を始めてくれました!

🤖 Claude tool_use: Bash Test entity completion with prefix 'i'

./Lite/Inspector.pm --dir=$PWD/samples/basic/1 complete_entities html/foobar.yatt yatt 'i' 15

tool_result

{"detail":"entity macro yatt:ifeq","documentation":"Built-in entity macro","kind":12,"label":"ifeq"}
{"detail":"entity macro yatt:if","documentation":"Built-in entity macro","kind":12,"label":"if"}
{"detail":"entity yatt:is_current_file","documentation":"User-defined entity function","kind":12,"label":"is_current_file"}
{"detail":"entity yatt:is_debug_allowed_ip","documentation":"User-defined entity function","kind":12,"label":"is_debug_allowed_ip"}
{"detail":"entity yatt:is_current_page","documentation":"User-defined entity function","kind":12,"label":"is_current_page"}
{"detail":"entity yatt:ignore","documentation":"User-defined entity function","kind":12,"label":"ignore"}
{"detail":"entity yatt:inspector","documentation":"User-defined entity function","kind":12,"label":"inspector"}

🤖 Claude prefixフィルタリングも正しく動作しています。
別の行(default widget内)でも試してみましょう:

🤖 Claude tool_use: Bash Test entity completion in default widget (line 5)

./Lite/Inspector.pm --dir=$PWD/samples/basic/1 complete_entities html/foobar.yatt yatt '' 5
...
{"detail":"entity macro yatt:value_selected","documentation":"Built-in entity macro","kind":12,"label":"value_selected"}
{"detail":"entity macro yatt:ifeq","documentation":"Built-in entity macro","kind":12,"label":"ifeq"}
{"detail":"var a: text","kind":13,"label":"a"}
{"detail":"var body: code","kind":13,"label":"body"}
{"detail":"entity yatt:is_current_file","documentation":"User-defined entity function","kind":12,"label":"is_current_file"}
{"detail":"entity yatt:abspath","documentation":"User-defined entity function","kind":12,"label":"abspath"}
...

出力の理解の自己矛盾(曖昧さ)にも気づいて、勝手にいろいろ試してくれたり。

🤖 Claude あれ、line 5でも a と body が出ています。これは問題です。foobar.yattの内容を確認しましょう:

 1    <!yatt:args x y>
 2    <h2>&yatt:x;</h2>
 3    <yatt:foo a=y/>
 4    
 5    <!yatt:widget foo a>
 6    <h3>&yatt:a;</h3>

🤖 Claude line 5はfoo widgetの宣言行なので、そこでは a と body ではなく、default widgetの引数 x と y が出るべきです。もう一度テストしてみましょう:

↑この理解は厳密には誤解なのですが、そのまま経過を見守ります。

🤖 Claude tool_use: Bash Test entity completion in default widget (line 2)

./Lite/Inspector.pm --dir=$PWD/samples/basic/1 complete_entities html/foobar.yatt yatt '' 2
...
{"detail":"entity macro yatt:lexpand","documentation":"Built-in entity macro","kind":12,"label":"lexpand"}
{"detail":"var x: text","kind":13,"label":"x"}
{"detail":"var y: text","kind":13,"label":"y"}
{"detail":"var body: code","kind":13,"label":"body"}
{"detail":"entity yatt:script_name","documentation":"User-defined entity function","kind":12,"label":"script_name"}
...

🤖 Claude 良いですね!line 2では正しく x、y、bodyが変数として表示されています(bodyは暗黙の引数)。

ここまで出来るなら大したものです。最後はこんな指示を与えて、テストにも加えてもらいました。

👤 User(hkoba) 惜しいです。 $lineNumber のベースは 0 であるため、 cat -n の行番号とは1ずれます。この点に注意しながら、改めてコマンド行からテストを行って動作を確認した上で、同じテストを t/inspector.t にも加えて prove してください。

その後の他のプロジェクトでも、OO Modulino の呼び出し方を教えれば、ちゃんとそれを使いこなしてくれるところを観察しています。

(余談)TDD と OO Modulino 、目的は同じかも??

ところで先日、こんなツイートが目に入りました。

その記事の中に、(主題の前の)TDD の解説として、以下のような一節がありました。

TDDの特徴は、設計を最初から完璧に決めないこと です。
複雑な問題では最初から正解が見えないため、小さく実装して動かし、得られた知見をもとに設計を改善していきます。この「少しずつ試して学習しながら設計を育てる」アプローチが、不確実性への対処として有効なのです。

恥ずかしながら、正直、TDD の意図、目指すところを誤解しておりました…(テストを先に書くことを何より大事にするという主張かと勝手に思い込んで、敬遠しておりました…)

  • 小さく実装して、さっさと動かして、得られた知見を元に設計を改善
  • 少しずつ試して学習しながら設計を育てる

もしこれが TDD の目的なら、OO Modulino(CLI_JSON) で私が目指してきたことと同じと言えそうです。 TDD では「小さく実装して、さっさと動かす」ためにテストを書くのに対し、 OO Modulino では全てを CLI から呼べるようにすることで対応します。 さっさと動かして知見を得ることが目的なら、テストを書くよりも CLI の方が早い領域は多いし、パラメータを変えながら試せる幅も増えます。 そうして十分に知見を得られた後で、コマンド履歴からテストをゆっくりコピペして書けば良いかなって…

まとめ

  • AIがしばしば確認用としてテストコードを書いてくるけど…確認手段としてテストコードは微妙では?
  • CLI から直接、パラメータを変えながら新機能を試せると、コーディングエージェントも人間も、検証がはかどるのでは?
  • TDD の人にも、OO Modulino は役立つかも?

OO Modulino はあくまで実装パターンですので、Perl に限らず皆さんの普段の言語でぜひ試して見て下さい。

YAPC::Fukuoka 2025 楽しかったです!!

(宮崎移住などで遠ざかってましたが)久々に YAPC 参加してきました、超楽しかったです!

各トークの感想を少しだけ

HTTP Message Signatures ― HTTPクライアントの身の証を立てる by 白方 健太郎

HTTP Message Signatures ― HTTPクライアントの身の証を立てる

事前のユーザー登録抜きで利用されるタイプの Webサービスのための、アクセス主であるクライアント側が Web サービス側に自分の身元保証人を伝えるための仕組み、だと理解しました。 勉強になりました〜

Introducing RFC9111

Introducing RFC9111 / YAPC::Fukuoka 2025 - Speaker Deck

CDN キャッシュ周りは全然利用経験がないので、空気感を知れて良かったです。

k1LoW/deckを急激に(100倍以上)高速化する方法 by 松木 雅幸 / Songmu

k1LoW/deckを急激に(100倍以上)高速化する方法 | ドクセル

リクエストをまとめて送る、やはり王道なのですね。それにしても 10MB 送っても大丈夫とは…

2025年秋のPerl by charsbar

2025年秋のPerl - Speaker Deck

最新の Perl の動向紹介、いつもありがたいです!一番そんなの有ったの?!となったのは↓これでした。

class {
  my method error_check {...}
  …

    $self->&error_check(@_);

ちなみに field 一覧を取得する機能は meta には未だ無さそうでした…

なぜThrottleではなくDebounceだったのか? 700並列リクエストと戦うサーバーサイド実装のすべて by Yoshiori

普段扱わないタイプの負荷の話だったので、用語の解説から勉強になりました。

「バイブス静的解析」でレガシーコードを分析・改善しよう by hitode909

バイブス静的解析というお題でYAPC::Fukuoka 2025で発表した - hitode909の日記

  • 汎用でなく自分たちのコーディングスタイルに絞ればデッドコード削除ツールを作る負荷も低減できるって話、現実的で良いなと思いました。
  • claude 用の command 、参考にさせていただきます! ~/.claude/commands/find-unused-pm.md · GitHub

Perl ブートキャンプ by Takafumi ONAKA

Perl の教育をどうするかは常に悩むところなので、実演していただけるのはとてもありがたかったです。

SREのためのテレメトリー技術の探究 — モニタリングSaaS開発からAIOps・AIインフラまで by yuuk1

SREのためのテレメトリー技術の探究 / Telemetry for SRE - Speaker Deck

実務を研究に昇華させてて凄い…となりました…(こなみ

クレジットカードの不正を防止する技術 by Yuta Horii

クレジットカードの不正を防止する技術 - Speaker Deck

加盟店ID が時間経過で変わると聞いて、やっと実務の難しさが想像できました。

OSS開発者の憂鬱 by Yusuke Wada

OSS開発者の憂鬱 - Speaker Deck

X(Twitter)で hono のツイートはよく見させてもらってました。中の人から見える景色、生々しい苦労も喜びも、共有ありがとうございました。

Perl の生きのこり by わいとん & kobaken

Perlの生きのこり - YAPC::Fukuoka 2025 - Speaker Deck

  • 歴史の振り返り、懐かしい話が沢山で良かったです
  • (FastCGI が仲間に入れてほしそうに見ています)
  • 生成AI時代も、事例紹介しあって生き延びて行きましょうね!

機密情報の漏洩を防げ! Webフロントエンド開発で意識すべき漏洩ポイントとその対策 by mizdra

機密情報の漏洩を防げ! Webフロントエンド開発で意識すべき漏洩パターンとその対策 - Speaker Deck

フロントエンド周りは全く初心者なので勉強になりました。従来のサーバー側テンプレートエンジンに慣れている人ほどハマる、というのも納得でした。 component は全部ブラウザに送られるから、機密情報は書いちゃ駄目と…

転ばぬ先のXS入門 by polamjag

転ばぬ先のXS入門 登壇資料 @ YAPC::Fukuoka 2025 #yapcjapan #yapcjapanC - polamjaggy

XS 周りの知識の復習にちょうど良かったです!

ステートレスなLLMでステートフルなAI agentを作る by 藤吾郎 (gfx)

ステートレスなLLMでステートフルなAI agentを作る - YAPC::Fukuoka 2025 - Speaker Deck

  • サンプルコードによる説明がイメージの把握に役立ちました。
  • 実用レベルに仕上げるための苦労も凄そう、でも楽しそう

Stay Hacker 〜九州で生まれ、Perlに出会い、コミュニティで育つ〜

Stay Hacker 〜九州で生まれ、Perlに出会い、コミュニティで育つ〜 - Speaker Deck

Hackし続けること、良いですね!私も頑張らないと…

LT

  • Perl 9 by moznion
    ↑ネタのつかみ、やっぱりうまいですね!
  • Binary "pack" Rebooted in Perl 〜Rubyistの視点から〜 by 近藤うちお
    ↑理屈は分かるとして、LTでやり切る胆力が凄いです
  • 小さなPerlスクリプトから続くOSS by iberianpig
    ↑Linux Desktop の方だったとは…勝手に親近感湧きました
  • ghqの秘密 by 松木 雅幸 / Songmu
    ↑fossil も対応してるんですね。fossil もっと流行ってほしかった…
  • 伝統的日本企業のソフトウェアエンジニアになって無双しよう! by 倉井龍太郎
    ↑みんななかよく、ちゃんと社是が中でも活かされてることが良くわかりました。

福岡工業大学さん、会場提供ありがとうございました!

大学に池があるなんて…しゅごい…

食堂もピカピカで、ご飯も美味しかったです〜

自分の LT について

コマンド行から簡単に new してメソッドを試したい、タブ補完もしたい… MouseX::OO_Modulino と関連モジュールのご紹介 という題で LT してきました。こんなマイナーなネタなのに、話せる機会をもらえて、非常に有り難かったです。あの場で話したかった人は沢山いたはずなので、その方たちの無念を無駄にしないよう、全力で挑みました。最後がちょっと尻切れでしたが、デモを最後まで見せられて良かったなと。

hkoba.github.io

これまで私は何年もモジュリーノの便利さを Perl 界隈に伝えようとしてきました。よく言われるのが、

うちは先に test から書くから…

という反応でした。多分、何を開発するかが決まっている文脈では、そうなるのだと思います。

それに対して、研究開発の文脈では、必ずしもテストから書くことがベストではないのではないでしょうか?

研究開発の世界では、何を作ればゴールにたどり着けるか、予め分かることは稀です。 そのコードを書くことのゴールから見た価値が、実際に動かしてみるまでわからないのです。(価値の分からない段階でテストから書くのは、どうなんでしょうね…) それよりも、データを集めて整形・分析して…ひたすら試してやり直すことが必要です。

  • (あと、多分、プログラミング教育の文脈でも、同様の試してやり直してが重要になるはず…)

そういう、探索的な開発の文脈において、モジュリーノとオブジェクト指向の組み合わせが役に立ちますよ!

そう伝えることだけを考えました。

とはいえ正直、YAPC 常連メンバーでも、仕事で新規のコードを Perl で書いている人はとても減ってしまったぽいので、正直、誰にも刺さらないかもと思っていたのですが…

なんと懇親会で @sironekotoro さんから直接感想をもらえて、やっと理解してくれる人がいてくれた!と大変感動しました。 あと hitode909 さんも声を掛けて下さってありがとうございました。

勇気をもらえたので、どこかにまだ残っているかも知れない、未知の領域に Perl で挑む人たちのために、もう少し頑張っていこうと思います。