推しのVTuberの3分タイマーをReactで作った

これ anatofuz.net

背景

最近(ここ数ヶ月)、自分としては珍しくVTuberのファンをやっている。 珍しくと書いたのは自分は別に今までアイドルファンとかにはなったことがなく、いくつかのVTuberも知っているもののYouTubeのライブを見るとかはしてなかったからだ。最近は珍しく見ている。

最近見ているVTuberは2人ほどいるが、その中に宝灯桃汁がいる。 桃汁ちゃんは山梨ご当地VTuberなので、地元応援的な意味で見始めたが、普通にハジケリストっぽい配信が個人的に好きで今に至る。

そんな中先日の七夕に開催されたリスナーからのお願いを叶える配信でリスナーからの「3分タイマーがほしい」という願いがあり、これに答える形でいい感じのセリフを喋る一幕があった。

www.youtube.com

このボイスは運営によって切り抜かれてショートになった

www.youtube.com

とはいえ3分たったといいつつショートなので10秒くらいで3分たってしまう。

マジで3分たったときにこのボイスが聞きたいのと、基本的にPCで作業をしているので、カップ焼きそばを食べるときにPCからタイマー3分設定するのが毎回大変な課題感が揃ったので、いい感じの3分タイマーをPCから使えるwebアプリの形で作ろうと思った。

ツイートしたところ運営のボスと司令官からも補足されたので本格的に作ることにした。

作ったやつ

anatofuz.net

おもしろ機能

3分タイマーとしては普通に使えるけどいくつかおもしろ機能をいれている

  • 待機BGMを選択可能に
    • プレ配信のときの桃汁ちゃんの「ナリ」が入っているBGMがそこそこ気に入っているのでこれで聞けるように
  • 再生中にCDが回転する
    • 後述するけどviteのデフォルトcssをちょっといじっただけ
  • コナミコマンドに対応している
  • 古のオタクらしくHTMLコメントでAAがでるようにしている

おだいじにって書いてるのはこのとき桃汁ちゃんが運営いれて全員コロナに罹患してたから。

技術スタック

ソースコードはこれ github.com

Vite + React(SWC)をTypeScriptで書いていて、ホスティングサービスはGitHub Pagesを使っている。手軽。

仕事でTypeScript + Reactを書いているけれど、実際仕事じゃないプロダクトを1から書いてみると、意外とReactが書けるようになってることが実感できてよかった。 あとcss苦手マンなのだけど、Viteの初期コードのcssが意外とちゃんとしているので、それを拡張することでアプリケーションの形にもなったのが良かった。ダークテーマ対応と絵をcssで回転させる技術をこれで初めて知る。

シュッと作りたかったのでnpmモジュールをフルで使っている。いれたのはだいたい次らへん

とくにuse-konamiはかなりお手軽にコナミコマンドを実装できたのでよかった。

音源はYouTubeからyt-dlpでmp3データ形式でダウンロードしてAudacityで3分に調整した。Audacity数年ぶりに使ったけどやはりシュッと音声が作れて便利だった。

おもしろ話題

id:anatofuzはマジでCSSが苦手なので勢いで作ったところ、沖縄時代からの友人のろくさいパイセンがPRを送ってくれてだいぶ見た目が改善されるなどした。

感想

思い返せばここ数ヶ月くらいプライベートでコード書いていなくて、仕事でしか書いてなかった。 仕事で書くコードもユーザーに価値を届けられているので虚無に消えているコードを書いている訳では無いのだが、どうしても仕事となると保守性や仕様の妥当性、タスクの段取りなど、素朴にコードを書く楽しみとは別のファクターで頭を使う必要がある。それらの所為というわけではないものの、仕事でコードを書いているとどうしても「楽しい!!!」というよりは「責任」とかの方に意識が向いてしまう。*1

久しぶりに完全趣味のコードを書いて、公開して、会社の人じゃない人からPRをもらったり、Twitterで反応をもらったりする体験だった。 なにかこうエンジニアになろうとした根源的な楽しさを久々に感じられた。こうみると、やはり自分はプログラミングが好きで、それで周りの人とワイワイしたり、自分が面白いと思っているものを作るのが好きなのだなぁというのを再認識できて、技術に対しての最近のモヤモヤが一つ解消できた気がする。

それはそうと桃汁ちゃんのコロナ明け配信は明日なので各自見ましょう。 そろそろデビューして一周年です。

www.youtube.com

*1:楽しく仕事が進められるように段取りを工夫しろと言われればそうなのだが....

golangのenumは型が違うと違うものとして扱われる

タイトルの通りです。

以下のようにint型のFooTypeBarTypeを宣言して、それぞれ60をenumで持つ値をチェックしてみます

package main

import "fmt"

type FooType int
type BarType int

const (
    Hoge FooType = 60
    Nyan FooType = 61
    Baz  BarType = 60
)

var someTypes = []interface{}{
    Hoge,
    Baz,
}

func main() {
    for _, t := range someTypes {

        if t == Baz {
            fmt.Println("same")
        } else {
            fmt.Println("difference")
        }
    }
    if Baz == 60 {
        fmt.Println("Baz is 60")
    } else {
        fmt.Println("Baz is not 60")
    }
}

出力

difference (`Hoge != Baz`)
same (`Baz == Baz`)
Baz is 60 

go.dev

ということでenumに設定した数値をリテラルで比較するとその値として出てくるけれど、enumで同様の値を持つ別の型の値と比較した場合は違う扱いになります。

つまるところgolangでは同じ数値範囲のenumも型を分ければ別物として扱えます。便利ですね。

YAPC::Kyotoの思い出 #yapcjapan

こんにちは。そろそろ京都に引っ越して3年のid:anatofuzです。

先日のYAPC::Kyotoではスタッフをしていました

yapcjapan.org

コアスタッフではあるものの、昨年末から今年にかけて引っ越しがあったり、本業の仕事もなかなか大変で平日は仕事をしてそれ以外のことができない、土日は疲労という感じで身動きが取れない、様々なことが発生してメンタルも死*1という状況が数ヶ月続いてしまい、あまり準備にコミットすることができませんでした。ここはid:papixさんはじめスタッフの皆さんに非常に申し訳なく思っています。

その分準備と当日のスタッフ業こそはちゃんとやろうとしていて、当日は土俵の部屋番長をやっていました。主にslack/twitterで状況を確認しつつ、タイムキープをしながらメンバーと連携していく係です。土俵のスタッフのid:tomcha0079さん、id:nhayatoさん、id:kaoru1615くん方のおかげではあるのですが、スケジュール通りで大変な問題も発生せずに無事おえられて何よりでした。

基本的にはそういったスタッフ業が中心であんまりカンファレンス中は人々と話したりするのがバタバタしていてできなかったのですが、数年ぶりにid:codehex先輩とあったり、大学の戦友のid:unimarimoPerl入学式方面やYAPC::Okinawaでの思い出深いid:note103さん、ずっと憧れであったゆーすけべーさんとお会いすることができて、自分が好きだったYAPC、コミュニティにまた復帰できた感じがしました。特に土俵でトークしていただいたid:ar_tamaさんは、Okinawa.pmでやったYAPC::Okinawaの立ち上げのときに知り合ったこともあり、あらたまさんとYAPCの関連がすごく印象に残っていて、そんなあらたまさんがちょうど自分が今悩んでいたエンジニアのキャリアについて眼の前でトークされているのは、まさにYAPCだな....という感じで感無量でした。

個人的には今回のYAPCではちょっとだけ、恩を返せたかなという出来事がありました。 学生時代にPerlコミュニティの支援でPerlConに参加させていただいたのですが、今回はその支援カンパの余剰分のうちの一部*2を学生支援スポンサーメインのスポンサーとして協力させていただきました。

会社という訳ではないので金額等柔軟に対応していただいたid:papixさんには感謝です。*3

anatofuz.hatenablog.com

個人的にはスポンサーして無事学生さんの旅費を支援できて満足という感じだったのですが、忘れていたスポンサーチケットを、ちょうど学生チケットの購入を逃してしまった学生さんにお譲りすることができることなどがあり、そういう意味でも今までコミュニティからもらえた恩を少し返せたかなとは思っています。

あとは沖縄から学科の後輩のid:e205723id:mattari_matayuYAPC::Kyotoに呼べたのが良かったかなと思っています。沖縄のPerlコミュニティにお世話になったので、沖縄の人々にもどうにかしておきたかった。

次回はYAPC::Hiroshimaになりそうな気配がありますが、個人的に地元の山梨でYAPCをやるまではやっていくぞという感じでもあり、今回あまりコミットできなかった分次はやっていきたいので、次回は広島でまたお会いしましょう。よろしくお願いします。

*1:引っ越しで貯金が無くなったり、京都に引っ越してから数年物理的に旧友とあってなかったり、仕事のコードばかりでテンションが上がる趣味のコードがかけなかったり

*2:20万ほど。残りはまたYAPCで使います

*3:スポンサー一覧に載せなかったのはなんか個人的に自分のアイコン乗せるのもな...というところです

PerlにおけるGraphQLライブラリのまとめ

リッチなフロントエンドを開発しているとGraphQLを使いたくなるときがあり、さらにそのバックエンドをPerlで実装したくなるときもあるでしょう。

このエントリではPerlでGraphQL開発をしたい時に使える2023/02/24現在のPerlのGraphQL周りのライブラリ事情についてまとめます。

GraphQLフレームワーク

graphql-perl

PerlCPANモジュールを使ってGraphQLバックエンドを実装したいとなった場合に現状コレ一択。

PerlCareersの支援で資金援助を受けて実装されている。

世界観としてはThis module is a port of the GraphQL reference implementation, graphql-js, to Perl 5.と言っているが、graphql-jsの忠実な移植ではなく、限りなく処理を独自実装しているのが特徴。

MooやType::TinyなどのモダンPerl的なライブラリをふんだんに使っていたり、GraphQLのパースをPegex::Parserを使い正規表現を用いて行っている。

やや実装に難がありパフォーマンスに問題が発生しがちな傾向にある。

khrt/graphql-perl

graphql-jsの忠実な移植プロダクト。 残念ながら開発が途中で止まっていそう。

stevan/p5-Graph-QL

khrt/graphql-perlと同様にgraphql-jsの忠実な移植。 開発が5年で止まって入るが、比較的実装されている。

パーサーライブラリ

GraphQL::Language::Parser

前述のgraphql-perlの一部分

Parser::GraphQL::XS

graphql公式のリポジトリにあるC++で実装されたGraphQLパーサー( https://github.com/graphql/libgraphqlparser )のXSバインダ。

ただしParser::GraphQL::XSにはlibgraphqlparserをインストールするみたいなおもてなしが無いことから、このモジュールをインストールする際は自前でlibgraphqlparserをインストールする必要がある。

DataLoader

GraphQLでクエリに対するSQLをいい感じにまとめる時に使われる機能であるDataLoaderの参考実装。 Mojoliciousが動いていることが前提となっているため、Mojoliciousを使っていないwebアプリケーションには直接組み込めない


というわけで基本graphql-perlを使えば良いのだけど、graphql-jsの素朴な移植もほしいですね。。。

Perlでスマートに配列からランダムで特定個数の値を取得する

TL;DR

use List::Util qw(sample);

my @array = (1..100);
# 3個ランダムでとりだす

my @random_pickup = sample 3, @array;

人間生きていると配列の中身からランダムにn個取得したいときがあります。Perl書いているときもありますね。

よくある方法は次のような感じでしょうか

my @array = (1..100);
my @random_array =  shuffle @array ;
my @random_pickup  = splice @random_array, 0, 3;

List::Utilのshuffleを使い配列をランダムにばらしたあとに、標準関数のspliceを使い特定の数の値を取り出してきます。 これだと@random_pickupには3つのランダムな数が入る訳ですね。

ただしこの方法だと必ず全件をshuffleしないといけないため、巨大な配列を対象にする場合はそこそこコストが掛かります。 他には結局@random_pickupが必要な場合は、中間変数の@random_arrayが不必要ですね。 (最も、工夫すれば中間変数を作らずにかけますが...)

そこでオススメなのがList::Utilのsample関数です。1.54から同梱されているので、比較的最近のList::Utilになら入っています。 ちなみにList::MoreUtilsにも入っています。

書き方は簡単で以下の感じです。

my @items = sample $count, @values; # sample {取得したい数}、 {リスト}

$count@valuesの配列長より大きい場合は、shuffleと同じ挙動になります。

近年のList::UtilはXS(C言語実装)も同梱されており、sampleも見てみるとC言語レベルで特定個数のランダム取得をしてくれています。 このため、コスト的にもshuffleしてからspliceなどで取得するより最適化されておりオススメです。 metacpan.org

2022年、CPAN(Perlの)モジュールのメンテナを引き継ぐ活動を始めた件

これははてなエンジニアアドベントカレンダー2022 42日目の記事です。 昨日は id:k-murakami0609 さんの 過去に所属してたチームに転生したら導入したいもの でした。

はてなのノベルチームで日常的に使っている便利グッズ最高ですね!! みなさんもノベルチームにjoinして体験してください!!!

さて今回は2022年にぼちぼち始めたCPANモジュールのメンテナを引き継ぐ活動についてお話しようかなと思います。

CPANモジュール

CPANモジュールとはご存知プログラミング言語Perlのモジュールシステムのことです。

Perlインタプリタに付随しているコアモジュールも含めて、PerlではCPANと呼ばれるアーカイブにモジュールがアップロードされ、cpanmcpmなどのツールを通してインストールし利用する世界観になっています。

TeXのモジュールアーカイブのCTANに影響されて作成されたと言われていることからも分かる通り、CPANは1995年から存在しており、歴史的にも古いシステムになっています。

そんなCPANには大小様々なモジュールがアップロードされています。特に有名どころではAcme名前空間でしょうか。 他の言語に無い特徴ですが、PerlのモジュールではAcme::と名前がつくモジュールはジョークモジュールとなっていて、様々なおもしろモジュールがアップロードされています。(どういう物があるか知りたい方はAcme大全がオススメです)

CPANモジュールの今

そんなCPANモジュールですが、Perl使用者の人口減に伴って、新規モジュール開発及びモジュールのメンテナが減少傾向にあります。

最近ではElasticsearchの公式クライアントライブラリのSearch::ElasticsearchもElasticsearch8を持ってPerlクライアントの提供を終了することを発表したりしています。

日本でもPerlを書かれていたエンジニアの方々が、別の言語にコミットすることになったり、また多忙でPerlを書く時間が取れなかったりと、様々な理由でメンテナが減少しています。 使わないモジュールのメンテナンスをし続けるのはなかなかしんどいですよね。

Perlではここ数年@INCがカレントディレクトリから削除されたことなどもあるため、継続してメンテナンスをしていくのは後方互換性が強いPerlといえども必要そうです。

とはいえ、はてな社にはまだPerlで元気に動いているPerlプロダクトがありますし、何よりid:anatofuzPerlが好きなので、できればモジュールのメンテは継続していきたいです。

他にはCPANモジュールではないですが、Perlの公式Dockerイメージの管理もごく数人で行っているので、こういったところにもコミットしたいなと思っていました。

CPANモジュールのメンテに関わる活動

そこで去年はパッチを当てたいOSSを中心にメンテナを引き継ぐ活動をしました。 そこまで件数が多いわけではなかったですが、声を書けながらメンテ権を頂いています。

溜まっていたPRの解決や、新規PRのレビュー等に参加することで、継続してメンテナンスを行っています。

github.com

直近ではTest::WWW::Stubのメンテに関わりました。

metacpan.org

モジュール以外ではdocker-perlやOpenAPIのスキーマからクライアントコードを自動生成するOpenAPI GeneratorのPerlクライアントもPRを送っています。

github.com

github.com

CIの修正なども

他にはPerlモジュールは、日本でよく使われるCPANモジュールオーケストレーションツールのMinillaが標準でTravis CI用の設定ファイルを出力していたことから、Travis CIでCIを回しているものが多かったです。

しかしTravis CIは近年では動かなかったりするので、これをGitHub actionsに移動するなどの活動もメンテ権をもらうついでにシュッと進めています。

github.com

CPANモジュールのメンテを引き継ぐ方法

CPANモジュールのメンテはGitHub等のリポジトリを引き継ぐ + CPANモジュールのcomaintに登録してもらうことで引き継ぐことができます。

gfx.hatenadiary.org

この部分はオリジナルの作者の方にやっていただく必要があるため、コミュニケーションが必要です。 権限を付与されてからは自分のCPANモジュールをメンテするように操作することが可能です。

ただし引き継がれたCPANモジュールをアップロードする際はx_authorityという権限に気をつける必要があります。

blog.64p.org

※追記 id:shoichikaji さんより最近はいらないとの情報を得ました!

※追記ここまで

新しいモジュールを作りつつメンテもしていく

新しいモジュールを作るのも楽しいですが、既存のモジュールのメンテをするのも盆栽をするようで楽しいです。 また偉大な先人のコードに自分も関わることができ、広く使われていく体験もできるので、ぜひPerlに興味がある方はCPANモジュールなどに関わっていきましょう!!!

明日のはてなエンジニアアドベントカレンダーは同じチームのid:deflis55さんです! お楽しみに!