perlと30年

タイトル通り、perlと長いつきあいになったなあ、というのが今回のエントリ。
還暦過ぎの爺さんの無駄に長いだけのネタですみません。
シンボリルドルフのダービーから競馬を始めた。1984年がわたしの競馬元年。
1991年にJRA PAT、馬券をパソコン通信で購入できるというので申し込み、たぶん2回めの募集で滑り込み、モデムやら回線、銀行口座やら揃えて、その延長でPC-VANに登録してパソコン通信を始めた。
すべては競馬ありきだった。
どっぷり競馬、馬券にハマって当時PC-VANの競馬SIGのひとたちと競馬データを分担して収集加工整形するようになった。
この競馬データいじりが、perl歴の始まりとなる。だいたい1990年代はパソコンをいじり倒してたと思う。
当時の仕事(エロ本エロ漫画編集)にはパソコンなんて1mmも関係がないし、1円にもならないことにほとんどの時間を使っていて、そんなことして何になるの?と言われると謝るしかない。
そもそも、競馬データを集めて解析分析したところで馬券には繋がらない。競馬に限らず、ギャンブルの本質は「気合と根性」だということがわかった。自分にどれだけのものを賭けられるか、その快感がギャンブルの麻薬的魅力。
最初はMS-DOSでawkを使っていて、次にjperlを使うようになって現在に至る…なので、30年ぐらいperlを使ってることになる。
この時やってたことが30年以上経ったいまになって使えるんだから、何が役にたつかなんて、わからないものだ。
perlを使うために
・MS-DOSではメモリも足りず、PANIXやFreeBSDといったPC-UNIXを使い
・perlはCGIに使われることもあってWEB(ホームページ)を作るようになり
競馬から離れたところでperlを使うようにもなっていた。
unixを構築したり、CGIを使うようになると、webやデータベース、メールサーバーなどのサーバー類も構築するようになった。
FreeBSD、apache、postgresql、mysql、sqlite、sendmailなどなど、どれも独学独習の素人芸。
IT業界未経験、ただの元エロ本編集という私立文系一本道の穀潰しでもそれっぽい仕事にありつくことができて、どうにか食えるようになってるのはperlのおかげだ。
perlとエロ本編集時代の知識でepub3電子書籍の制作もできてるし。
21世紀のいま、perlは終わった言語という扱いらしい。
いまどきのrubyやpython、GOなんかは精力的に開発されていて、バージョンアップ、アップグレードも頻繁で改善されている。その点perlは音沙汰もない。ほとんどのunix系OSにはデフォルトで入ってるんだけどね。
でも、今も昔も変わらない、枯れた言語だからこそわたしは助かってる。
どのIT現場でも30年前の知識が通用するわけだから。perlひとつでどうにかしてきた。
ほかの言語だとアップグレードについていくのが大変で投げてたと思う。
いやいや、perlがいま何か貢献してるわけ?とか言われるとわからないし、時代の進歩にあんまり貢献してないと思う。
けど、わたし個人、還暦過ぎ爺さんにはとても役に立ってくれてることは確か。それはそれでいいんじゃないのかなあ。


爺さんが説教くさいことをひとつだけ言うとしたら
コスパとかタイパとか効率などというのは、その時じゃわからない、いつ何が身を助けることになるかわからない。だったら好きなことを一生懸命やった方が面白いんじゃないかなあ、ということかな
ActivityPubの投稿削除

ActivityPubの投稿を削除するには2つ必要で。
・自分んち、ローカルは
→データベースから該当の投稿を削除する。
・他所んち、リモートには
→「Delete」のActivityをリクエストする。
今回のネタはこの2つ。
1)なんでautoincrementを設定してなかったんだ!?
2)Mastodon系とMisskey系で削除したNoteのIDの扱いが違っていた?

この投稿のうち、真ん中の2つ「6453」と「6454」は一度削除後に再投稿したもの
・一度データベースから削除
・DeleteのActivityをリモートにリクエスト
・削除されていることを確認して
・削除後に新たに別の内容を投稿したもの
ローカルから消すために、データベースからの削除はスグできる。
リモートには、対象の投稿はもう「墓石」です、というのを「Delete」のActivityに入れてリクエストする。
{「投稿を削除する::On Golden Pond」
"id":"https://tokoroten.doncha.net/t2aki/items/03881-20250208",
"url":"https://tokoroten.doncha.net/t2aki/items/03881-20250208",
"type":"Tombstone"
}
https://www.doncha.net/activitypub/activitypub007.html
お相手は削除のリクエストが飛んできたのを見て、対象のNoteは墓の下になったということで、タイムラインからも削除する。
そのIDはもう使えない。
削除後に新しく別のものを投稿すると
データベース的には、primarykeyにautoincrementを設定してないもんだから、IDの最大値を使う。
つまり、一度使用した・削除されたIDをまた使うことがある(IDの使い回しなどあってはいけない自業自得案件)
削除したIDを使い回して新たに投稿
mastodon.social

misskey.io

そもそも、IDの使い回しなどあってはいけない、というのが大前提なので、わたしのポカなんだけど。
mastodonは削除IDの復活はない、misskeyは削除IDを墓の下から復活する。
同じIDの使い回しというと「Update」(投稿の編集更新)があるけど、これもサーバーによって対応がビミョーに違ってた、かなあ。
IDの使い回しなどあってはなりません(教訓
SQLiteはAlterなんちゃらでautoincrementを後付けできない。
改めてテーブルを作って、そこに既存データをコピーすることになる…ので、いろいろ危険だなあ。これは「運用でカバー」という腐った対応にしておこう。そのためのメモだ。
[12/10 20:30:37] 追記
言い訳をしておくと。
mastodonの仕様は把握していた。miskkeyが意外だった。
autoincrementをつけるかどうかは、データベースを作る時にちょっと迷った。
投稿作成フローで、うちはまず「下書き」状態でデータベースに登録。この時点でIDがふられる。下書きを確認した後、問題がなさそうだったらリモートに配送する。
ということは、実際に配送に至らなかった投稿でもIDを消費してしまう。これを嫌ってautoincrementを見送ったという経緯。配送IDとか別建てにしておけば良かったんだろうけど…手抜きしちゃったなあ。
日常雑感

その時々のできごとや思ったことはリアルタイムWEBのSNS(フェディバース)に放流。
あとから参照することもありそうなことは蓄積型のこのブログに積み上げ。
という大雑把な棲み分けをするようにしてるつもり(SNSのなかった昔はともかく)
…なんだけど、ここ最近みたニュースがもうほんと未来に来ちゃってスゲー! ので、こっちに。
「核融合 小さな太陽を造る壮大な実験「ITER」は人類のエネルギー危機を救えるか?」
https://natgeo.nikkeibp.co.jp/atcl/news/25/102100578/
「核融合発電の技術開発で日本がリード、最終実証装置の建設に着手」
https://monoist.itmedia.co.jp/mn/articles/2510/29/news037.html
核融合なんて、太陽を手に入れるようなもので、人類には無理、と言われてたと思う。
まさかその太陽が手の届くところまできてた。びっくりするしかない。
イカロスになりませんように、だなあ。
核融合が実現すると、核廃棄物、地球温暖化CO2問題なんかが解決する、らしい…生きてるうちに知りたい世界だよなあ。
「HTV-X1号機、軌道制御マヌーバを完了し、油井宇宙飛行士によって把持(キャプチャ)されました」
https://humans-in-space.jaxa.jp/htv/mission/htv-x1/news/detail/005078.html
宇宙ステーションが地球の周回軌道にいて、そこに滞在する宇宙飛行士がいるだけで、それいつのSF?という世界で改めて胸熱なのに、地上から打ち上げた貨物宇宙船で荷物を届ける世界だ。
計算通りということだろうけど、いったいどれだけの距離がある? どんなスピードで地球上を周回してる? それをピンポイントでドッキングとか。
JAXAやNASAの動画を見るといま自分はどんな世界にいるのかくらくらしてくる。
いやまじで未来。
先日上げたエントリの続きも少し。
たぶんA.I.のクローラー。その連続アクセスがちょっと行儀が悪くてアクセス制限をかけた。
かなり雑にやっちゃったもんで、クローラーじゃない「ひと」も巻き込んでしまった。
ということで少しずつ様子を見ながら制限することに。

↑クローラーと思しきアクセスはこのページに案内するようにした。
A.I.も未来なんだけど、なんか不幸な生い立ちになりそうだなぁ
テキトーフェッチメール

プロバイダのメールを取得表示するperlスクリプトをでっちあげた。
今まではgoogleのGmailでプロバイダのメールを取得して、WEBやアプリのGmailでメールを確認してたんだけど、GmailがPOPのサポートを終了という話。
となると、迷惑メール=SPAMメールが面倒くさくなる。
Gmailを使ってる一番のメリットは迷惑メールの振り分け。迷惑メールフォルダは中を確認することもなくそのまま全削除してた。
これが使えなくなる。
WEBサービスを公開してたり、ブログで仕事受注していたこともあって、プロバイダのメールアドレスはオープンにしてた…なもんで、お問い合わせやプロモーションなどのメール以外、残り95%ぐらいは迷惑メール。
GmailのPOPサポートが終了となってから慌てても、空白期間が生じるんで、今のうちに対応しておこうというところ。
やることは単純で。
・pop3でプロバイダのメールサーバーにログイン
・届いてるメールを取得してログアウト
・メールの中身を確認、解析
・迷惑メールは削除
・迷惑メール以外は表示
これだけ。
Net::POP3を使ってメールサーバーにログイン、取得。
MIME::Base64とMIME::QuotedPrintを使ってメールのエンコードされている部分(本文やSubject、From)をデコード。
メールのヘッダーを解析するためにMIME::Emailというモジュールがあるんだけど、レンサバのロリポップにはインストールされていないので、ここは自作実装。
問答無用のスパムリスト
sub list_spam{
my $self = shift;
my $args = shift;
my @list = (
’[spam]’,’bizocean’,’visa’,’JACCS’,’ETC’,
’日本郵便’,’楽天会員’,’楽天カード’,’東京電力’,’セゾンカード’,’宝くじ公式’,’メルカリ’,’マネックス’,
’大和証券’,’クロネコ’,’ソースネクスト’,
’マイル’,’マイレージ’,’お客様サービスセンター’,’入金’,’分割・リボ’,’統計調査’,’即日’,
’裏ワザ’,’サービス停止’,’セキュリティ警告’,’無料でもらえる’,’ガス料金’
);
map {$_= quotemeta($_)} @list;
return join(’|’, @list);
}
プロバイダのメールで登録していない銀行やサービスは明らかにスパムだし、それ以外の「裏ワザ」「即日」といった文言を使うようなもの、「サービス停止」だのプロバイダのメールアドレス宛に飛んできそうにないものを列挙羅列して、SubjectやFromに含まれていたら削除。
このほか、ワードの組合せや本文中に含まれるリンクなんかでも判定を入れたので迷惑メールはほぼほぼシャットアウトできたと思う。
また、これらの判定の前にホワイトリストを通すようにしてるんで、必要なメールを削除するようなことはないだろう。

gmailをありがたく便利に使わせてもらってるんだけど、いつかのSPFレコードうんぬんの時も、gmailの仕様変更(?)は、影響が大きいんだよなあ。
ActivityPubサーバーで投稿の編集

フェディバースのタイムラインに定期的に流れてくる「投稿を編集したい」「編集できるの?」
これは
「サーバーが対応していれば」投稿の編集更新はできます。
ということになる。
自分のいるサーバーが
「投稿の編集」に対応しているなら「編集」して書き直した投稿はホームタイムライン、ローカルタイムラインに反映される。
「投稿の編集」に対応していなければ「編集」するリンクがなかったり「破棄して下書きに戻す」になってたりする、はず。
さらには、投稿の編集に対応している自分のいるサーバーで「編集」しても、フォロワーさんのいるサーバーが対応しているとは限らない。
自分は編集して、ホームタイムラインを見たら誤字も直ってるのに、編集更新未対応のサーバーにいるフォロワーさんのタイムラインでは誤字のまま、ということが起こる。
で、どうしてサーバーごとで対応が違うのかということになるんだけど。
(また、なんか前置きが長くなりそうな…)
ActivityPubの仕様に「Update」というActivityがある。
https://argrath.github.io/activitypub/#update-activity-inbox
これを使ってリクエストを投げれば、文字通り、投稿だけじゃなくてプロフィールなども「アップデート」=「編集更新」することができる。
仕様上できるとはいえ、投稿(Note)の編集更新(Update)はちょっと考えなきゃいけないこともある。
1)1つの投稿には1つのIDが振られる。
2)IDが(No.123)の投稿「タヌキそばとキツネうどん?そりゃタヌキそばに決まってるよ!」がタイムラインに流れてきたのを読んで「おれもだ!」と賛同の「イイネ」
3)後日、ID(No.123)の投稿を見てみたら「タヌキそば?ぷぷぷ、キツネうどんに決まってんじゃん」
4)え?なんで?おれの「イイネ」はたぬきそばにつけたんだが?
投稿の編集更新は、同じIDなのに、中身が全然違ってしまう、ということが起こるかもしれない。
なもんで、Update、投稿の編集の実装には慎重になるということもあるんじゃないかな。
「編集する」ではなくて「破棄して下書きに戻す」(改めて新規投稿する)
という方法で、別IDを振ることで上記の問題は回避できる。
投稿を編集したい・書き直したい、という要求の一番は「誤字脱字の修正」ぐらいだろうし、そんな神経質にならんでも?
とはいえ、不特定多数の参加するコミュニティだし、リスク回避最優先、てことかなあ。
とか、是非の分かれるところがあったりなかったり。
わたしは、ひとつのIDの中身が変わるのは気持ち悪いんで、削除&新規投稿の方がいいかなあ(誤字なんかは後からいくらでも湧いてきてキリがないので放置)
編集更新と違って、削除はだいたいすべてのサーバーが対応してるし。
とはいえ、NoteのUpdate実装は手間もないので実装済(送信)
(受信については、ウチはそもそも投稿の保存数が上限20個なので、Updateが流れてきた時にはすでに元の投稿は流れた後、ということもあるんで未実装)
UpdateのActivityが以下
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"Hashtag": "as:Hashtag",
"toot": "http://joinmastodon.org/ns# ,
"Emoji": "toot:Emoji",
"sensitive": "as:sensitive",
},
"https://w3id.org/security/v1"
],
"type": "Update",
"id": "https://tokoroten.doncha.net/t2aki/d378b480-a8b3-11f0-a5cb-d391bfe3cb70",
"url": "https://tokoroten.doncha.net/t2aki/d378b480-a8b3-11f0-a5cb-d391bfe3cb70",
"published": "2025-10-14T04:11:14Z",
"actor": "https://tokoroten.doncha.net/t2aki",
"to": ["https://www.w3.org/ns/activitystreams#Public"],
"cc": ["https://tokoroten.doncha.net/t2aki/followers"],
"object": {
"type": "Note",
"id": "https://tokoroten.doncha.net/t2aki/items/05976-20251014",
"url": "https://tokoroten.doncha.net/t2aki/items/05976-20251014",
"published": "2025-10-14T04:04:32Z",
"to": ["https://www.w3.org/ns/activitystreams#Public"],
"cc": ["https://tokoroten.doncha.net/t2aki/followers"],
"attributedTo": "https://tokoroten.doncha.net/t2aki",
"content": "編集更新対応の確認\u003cbr /\u003e→ここは対応している",
"updated": "2025-10-14T04:11:14Z",
}
}
Updateのオブジェクトに、編集したNoteのJSONに「updated」を追加して、リクエストを投げると受け取ったサーバーがUpdateに対応してれば、編集更新を反映してくれる。

↑mstdn.socialで受け取って編集が反映してるところを確認。
ちなみに「updated」の追加が必要なのはMastodonで、Misskey系iceshrimpは「updated」は不要だった。
サーバーごとで微妙に違うことが多いので、やっぱり現物合わせになる…
これもホームページの「おひとり様ActivityPubサーバーの自作実装」に追加しておこう。

