No day younger than today

RubyとかRailsとか蒙古タンメンとか

4 月から大学生になります。

年明け前くらいから検討、準備を進めてきて、今日付けで帝京大学理工学部情報科学科 通信教育課程に入学が許可された。
通信制で科目が CS に特化していて学位も取れる大学というのはそう多くなかった。かつ学費もそんなに高くないというあたりで帝京大学は今の自分にぴったりだった。

www.teikyo-u.ac.jp

そういうわけで 4 月から大学生になる。通信制なのでキャンパスに行くことは基本的になさそう。フルタイムで仕事をしながら勉強することになるので、今まで以上に時間管理をしっかりしなくちゃぁな。

なぜ今さら大学なのか

理由は 3 つほどあるが、今さらと言えど今が残りの人生で一番若い時なので、思い立って熱があるうちにチャレンジしてみようと思ったのです。

最近感じる「気持ち悪さ」

この 3 月でエンジニアになって丸 2 年が経過した。Ruby, Rails を使った開発でできること、わかることが増えてきた反面、もっと下のレイヤーで何が起きてるのかは全然知らないなと感じている。

それを強く感じたのはパフォーマンス改善に取り組んでいる時で、例えばインデックスを貼ると検索効率が上がるよね、とかそういうことはわかるのだけど、じゃあそもそも RDBMS ってどういう検索の仕方をしているんだろうとか、実行計画をどう策定しているんだろうとか、そういった疑問が湧いてくることが増えた。「SQL で取り出したデータを Ruby でごにょごにょするよりも、SQL 一発で取る方が速い」とかも、知識として知ってはいるけどじゃあ具体的な理由ってなに?というのが全然わからなかったりする。

プログラミングという手段の「使い方」というのはいろいろわかってきたけれど、もっとその根底にある「前提」のようなものがすっぽり抜け落ちているような感覚・・といって伝わるかわからないけれど、そこを埋められるんじゃないか、と考えたのが一番の理由です。

自分の興味のベクトルを知りたい

以前は型に関するライブラリにコントリビュートしていたけれど、型というものに夢中になっていたか、と言われるとそういうわけでもなかったと思う。たまたま触る機会があり、たまたまコントリビュートできる部分があり、それが登壇に繋がったりしたので興味があるのは間違いないのだけど。できそうなことがあるからやっていた、という感覚に近いと思う。
じゃあ何に興味があるんだと考えると、パッと思い浮かぶものがない。それが悪いことではないとも思うのだが、やっぱりこういう分野に興味があるとかこの分野ならけっこう詳しいっすよとかが欲しかったりする。

4 年間いろいろ学ぶ中で、自分が夢中になれるもの、それこそ「大学院に進んで研究したい!」と思えるくらいのものに出会えればいいなと思っている。

選択肢の幅を狭めたくない

僕は高卒で学位もない。いろんな人の話を聞いていて、海外の企業に勤めるには学位が最低条件として必須、という話を聞いている。

今の段階で海外の企業に勤めたいと思っているわけではない(むしろ転職すら考えたことがない)けれど、将来的にそういうチャレンジをしたくなる日が来るかもしれない。そうなった時に、「あの時学位を取っていれば・・」みたいな後悔はしたくないな、と思っている。チャレンジしたいと思った時にその資格すらないのは、悲しいので。

何を学ぶのか

コンピュータサイエンス(取得できる学位としては「工学(Engineer)」のようだけど)。カリキュラムとしては 学部要綱 の p.35 あたりに載っています。興味があれば眺めてみてください。この中から 4 年間で 124 単位取得すれば卒業できるらしい。

すでに各年度でどの科目を受講するかは決めていて、専門科目はすべて受講したいと思っている。ぜんぶ楽しみ!

出願のあれこれ

入試のようなものはなく、基本的に出願すれば入れるものなのだと思う。一応選考はしていると書かれているけれど、個人情報とちょっとした作文くらいなものだった。高校を卒業した証明書など、出願資格があることを証明する書類を集めるのは少し面倒だったけど。それも Web で申し込みできたので、出来上がった書類を受け取る時くらいかな。

出願の申し込みも Web からできたのは楽でよかった。書類を印刷して投函する必要はあったけれど、書類はほとんどが Web で入力したものが印字されるので字をあまり書かなくて済んだのもよかった。

入学に向けた準備

今日発出された案内では「入学式」があることと「4 月初旬にいろいろ送りまっせ」というだけのものだったので、準備という準備はいらなさそうではある。

が、必修科目に数学や物理があることはわかっていたので、ド文系部活少年だった僕は年明けくらいからスタサプで一生懸命勉強してる。やらないときっとついていけないと思ったので・・

learn.studysapuri.jp

何をやればいいのかわからなかったので、中学数学、数I、数A、数II、数B、物理基礎あたりの講座を片っ端から進めている。世の中の学生さんたちはこんな難しいことを毎日やっているんだなぁ。高校には通っていたはずなのに、ほとんど記憶にないのが不思議。

おわり

4 年間という長い闘いになるので、続けられるかが一番の心配です。挫折したら、笑ってくださいw

いい加減 pp '=' * 100 とか書くのが面倒なので gem にした

こんにちは、ふーが です。

この記事は、僕の勤務先である永和システムマネジメントが主催している ESM Advent Calendar 2023 の 1 日目の記事です。

pp '=' * 100 してますか?

僕はしています。それはもう毎日のようにしています。

debug gem とかを使った方がいいとも思うのですが、お仕事のアプリケーションでは諸般の事情により使えなかったりすることもあります。また、毎回ブレイクポイントで止まって欲しいわけではなく、いくつかのテストを流しながらその時々の変数の状態を見たい、というケースもあるでしょう。

そんな時は大体

pp '=' * 100
pp variable.class
pp variable.something
pp '=' * 100

などと書くことになります。

面倒、とにかく面倒

そんな感じでデバッグをしている僕ですが、1 日に何十、何百回とこういうのを書くことになります。とても面倒です。それはもう面倒です。

gem にした

そんなわけで、面倒ではなくなる gem を作りました。その名も ByeByePp です。名前の由来はそのまんまです。 github.com

まだ出来立てほやほやです。

どんな gem ?

使い方としては README に書いてあるまんまです。が、ここでもさらっと書いておきます。

今までは以下のようにデバッグしていました。

a = 'This is A.'
b = 10
c = %w[one two three]

pp '=' * 40
pp a.class
pp a.inspect

pp '=' * 40
pp b.class
pp b.inspect

.
.

(まぁ pp はそもそも inspect をしてくれるのだけど…)

ByeByePp を使うと以下のようになります。

require 'byebye_pp'

a = 'This is A.'
b = 10
c = %w[one two three]

bbpp a
bbpp b
bbpp c

bbpp メソッドに出力対象を渡すだけです。

すると、以下のような出力が得られます。

========================================
class: String
inspect: "This is A."
========================================
class: Integer
inspect: 10
========================================
class: Array
inspect: ["one", "two", "three"]

手軽に使えてべんりですね。

実装

実装は非常にシンプルで byebye_pp/lib/byebye_pp.rb の 1 ファイルにすべてまとまっています。特別なことは何もしていません。最後に Kernel.include しているので、pp や puts のようにどこででも使えます。

ただ、このメソッドは最後に puts していて戻り値が nil なので、テストをどうしようかと思っていたのですが、expect { ... }.to output(...).to_stdout という書き方で標準出力をテストできると知って勉強になりました。

今後の展望

ひとまず最低限めんどくさい状況を回避できるようにはなったのですが、もう少し実現したいことがあります。

bbpp の引数として渡されたものを文字列として出力したい

これは must で早急にやりたいことなのですが、たとえば先ほどの例をもう一度見てみます。

require 'byebye_pp'

a = 'This is A.'
b = 10
c = %w[one two three]

bbpp a
bbpp b
bbpp c

出力は以下です。

========================================
class: String
inspect: "This is A."
========================================
class: Integer
inspect: 10
========================================
class: Array
inspect: ["one", "two", "three"]

これくらい単純ならいいのですが、変数 a の出力がどれで、変数 b の出力がどれなのかがぱっと見でわからないんですよね。全てが順次実行ならいいのですが、並列処理でコードの記述順と出力順が入れ替わるケースだったり、真偽値をいくつも出力したい場合とかはけっこう不便になりそうです。

例えばですが、出力が以下のようになるとうれしいなと思います。

========================================
[ a ]
class: String
inspect: "This is A."
========================================
[ b ]
class: Integer
inspect: 10
========================================
[ c ]
class: Array
inspect: ["one", "two", "three"]

一応、手元では TracePoint を使って以下のようにすることで上記のような出力にできました。

module ByebyePp
  def bbpp(obj)
    text = <<~TEXT
      #{'=' * 40}
      [ #{$var} ]
      class: #{obj.class}
      inspect: #{obj.inspect}
    TEXT

    puts text
  end
end

Kernel.include ByebyePp

TracePoint.trace(:line) do |tp|
  @b = tp.binding
end

TracePoint.trace(:call) do |tp|
  next unless tp.method_id == :bbpp

  objects = tp.binding.local_variable_get(:obj)
  $var = @b.local_variables.detect { |v| @b.local_variable_get(v) == objects }
end

ただ、これだと bbpp メソッドの引数が変数である場合は問題ないんですが、引数でない場合は $var が空になってしまいます。例えば以下のようにメソッド呼び出しの結果を確認したいケースなどです。

require 'byebye_pp'

a = 'This is A.'

bbpp a.method(:shufle).source_location

以下のような出力を得られるのがベストです。

========================================
[ a.method(:shufle).source_location ]
class: ...
inspect: ...

こういったケースへの対応策は今のところわかっていない状況です…。どなたかアドバイスをもらえたらうれしいです。

出力内容を柔軟にしたい

これは願望レベルでまだ実装については何も考えていないのですが、今は class と inspect だけ出力しているのを柔軟にしたいというのがあります。例えば以下のように書けるとうれしいかなーと考えています。

require 'byebye_pp'

a = 'This is A.'

bbpp a, methods
========================================
a.methods: [:encoding, :force_encoding, :slice, ...]

なんか Object#send とかを使う形になりそうでおもしろそうです。が、まだドッグフーティングがあまりできていなくて本当にこれが使いやすいのかどうなのかわからないのでもう少し様子見かなぁ。

おわりに

日々のちょっとしたストレスを自分で解消できたのはちょっと自信になりました。もっとメタプロに詳しくなればやりたいことに対しての実現のためのアイディアの幅が広くなりそうだと思い、メタプログラミングRuby 第2版 を読み始めたりしています。

また日々のちょっとしたストレスがあれば gem なりメタプロなりを使って解決したい気持ちです。

おわり

Kaigi on Rails 2023 で登壇してパフォーマンス改善の話をした

Kaigi on Rails 2023 は東京・浅草橋で 10/27, 28 の 2 日間開催されました。僕は Organizer として運営にも携わっていたのですが、今回は登壇者としての参加録として書きます。

登壇内容

登壇資料はこちらです。

タイトルからもわかる通り、エンジニアになって初めてパフォーマンス改善に取り組んでからの今の自分との差分が主な内容の登壇でした。"パフォーマンス改善" というワードは聞いたことがあるしなんとなく "アプリケーションのレスポンスを速くするための取り組み" であるということは理解しているけれど、どのような手順で、どのような手法で改善を進めればいいのかがわかっていなかった過去の自分に対して、道筋を示せるような登壇をしたい、と思ったのがきっかけでした。

見る人が見れば当たり前のことを話しているだけかもしれないですが、その当たり前の部分を価値のあるものとして言語化できるのは(経験も知識も少ない)今の僕だからこそできることだと思っています。来年の僕には話せないことかもしれない。だから今年の Kaigi on Rails で話す機会をもらえたことがとてもありがたいです。

ターゲットとしては newbie 向けの構成にしていましたが、存外諸先輩方からも「よかった」とのお声をいただけたのが嬉しい誤算でした。

感想

いつも感じることですが、オフラインでの登壇はやはり楽しいです。自分が話していることへの反応が遅延なく表情や顔の動きで見て取れるのはもちろん、登壇後も SNS での盛り上がりを見返すことができる。一度で二度おいしいとはこのことです。
今お仕事でお世話になっている方々も見に来てくださっていたり、勤務先である永和システムマネジメントのメンバーが会場の一角の席に集まってみてくれていたのも応援団感があってありがたかったです。

今回 15 分枠だったのですが、登壇資料を作っていると話したいことが溢れてきてしまうんですよね。初版の資料で通しで時間を測ったら 21 分とか掛かっていたのでスライドを削ったりしていたんですが、削ってるはずがなぜかスライドが増えるという "何を言っているかわからねぇだろうが…" みたいな状況になってしまっていました。仕方ないので削るのは諦めて早口で喋るという選択をしたため、お聞き苦しいところがあったらすみません。大きく時間オーバーせずに済んでよかった。

登壇後

これもいつも言っている気がするけれど、直接のフィードバックは本当にうれしいので伝えてくださった皆様には本当にわざわざありがとうございます、という気持ちです。登壇を見てくださった方はもちろん、(マルチトラックだったこともあり)見れなかったけど登壇後にアップした資料を見て感想を伝えてくださる方もいたりして、やっぱり Rubyist は nice だなーと感じたりしました。「見てないんですけど…」って本人に言いづらいじゃないですか。そんな中でも良いと感じた部分だったり共感した部分を伝えてもらえるのは登壇者として救われるなーと体感したので、良いと思ったことは伝えるムーブをやっていきたい(この話は前にもした気がするけれど、改めて)。

会期中、懇親会や n 次会含めご一緒してくださったみなさんありがとうございました。特に今回は "SNS でお互いの存在は認識しているけれど、ちゃんと話したことのない方" とゆっくりお話しできたのがうれしかったです。人見知りなのでつい慣れた人との場に行きがちなのですが。予定調和でない集まりというのも楽しいな〜ということがわかってよかったです。

おわりに

Kaigi on Rails は来年もオフライン開催の予定なのでまたプロポーザルを出すぞ。あとはやっぱり登壇者として参加するカンファレンスは最高に楽しいので、これからもどんどん登壇していこう。RubyKaigi 2024 へのプロポーザルはなんとしても出したいので Rubyist やっていくぞ〜。

運営のみなさん、関わってくれたみなさん、ありがとうございました!
次は 11 月に松江でお会いしましょう👋

RubyKaigi 2023 in Matsumoto に行ってきました

ぼくと RubyKaigi

今年もたくさん友だちができて一緒にご飯を食べてお酒を飲んで Ruby コミュニティを全身で浴び続けた 3 日間でした。去年の津以来の方、カンファレンスでよく会うね、な方、パケット通信しかしたことない方の実体を確認できたりしてよかったです。特に @koic は入社当初毎日 1on1 をしてもらったりカンファレンス登壇に向けて背中を押してもらったりめちゃくちゃお世話になっているのにオンライン時代ならではの RubyKaigi 2023 で初対面となりました。

こうして社内のメンバーと大人数で集合写真撮れたのも嬉しかったー

トークの感想はまた別でかければと思っているのでその他のよかったことなどを書きます。

昨年の登壇は忘れられていなかった

「去年登壇していたふーがさんですよね?」という風に話し掛けてもらえることがけっこうあってうれしかったです。1 年越しに発表のフィードバックをもらえるなんて思ってもみなかったのでうれしい誤算でした。

僕が去年話したのは「gem_rbs_collection へコントリビュートする方法」だったのですが、それを聞いて実際にコントリビュートしてみました!とか後輩のジュニアエンジニアが刺激を受けて OSS 頑張っているみたいだよ!なんていうお話しを聞けたりして、自分が何かのきっかけになれるというのはこんなにもうれしいものなのだなと胸が熱くなりました。

RBS や Steep のメンテナと話せた

コミッタの方が一堂に会する貴重な機会なので少しでも話せたらと思っていたのですが、特に興味のある型周りの開発をしてくださっているメンテナの方とお話しできました。特に現状の課題感みたいなところだったり今後の展望みたいな部分は現場感のある生々しいお話しが聞けて僕自身も考えるきっかけになりました。

その中でもできそうなことやジャストアイディアも出てきたので形にできたらいいなと思っています。

Kaigi on Rails チーム(一部)でランチができた

KoR のオーガナイザーは全国津々浦々の Rubyist が集まっているのでなかなか膝を突き合わせて食事する機会はありません。今年は KoR もオフライン開催する予定ということもあり直接お話ししたいなーと思っていたところ、一緒にランチに行くことができました。

また野生の @_4geru と夜の街でばったり会ってそのまま一緒に飲みに行ったりもしたし、野生の @okuramasafumi と〆のラーメンに行ったりもできました。他のメンバーとも別の機会で交流したいです。

お世話になってるアプリ開発者に感謝を伝えられた

スポンサーとして参加されていた企業のアプリにプライベートでお世話になっているのですが、特に RIZAP さんに感謝を伝えたいなと思っていました。トレーニング習慣が付いたのは chocoZAP のおかげだからです。
ありがたいことに chocoZAP と書かれたわかりやすい T シャツを着ていたのでお声がけして感謝を伝えられました。

これから運動を始めたいという方に chocoZAP はとてもおすすめです。

chocozap.jp

ダーツ仲間と出会えた

趣味でダーツをやっているのですが、Rubyist 界隈でダーツをやってる方とはこれまで知り合えていませんでした。でも今回でダーツをやっている方がけっこういたり、興味を持ってくれる方もいるということがわかりました。
Day 0 に一人で行ったダーツバーに、翌日 7 人で行けたのは最高だったなぁ〜!一部の方とは「ぜひ東京でも一緒に投げましょう!」と約束して別れたので絶対実現したい。

今回はご一緒できなかった方にダーツやってるとか興味あるという方がいればぜひ投げましょう〜!僕はカンファレンスの度に現地のダーツバーに行くのが趣味なのでw

やはり登壇したい

会期中ずーーーっと思ったのはやっぱり登壇したい!!ということです。他の人の発表を見てるときはもちろんそうだし、やっぱり RubyKaigi のメインコンテンツはトークなので、自分もメインコンテンツの 1 つとして RubyKaigi を盛り上げるファクタになりたいんですよね。だから来年はそこを目指していきたいし、そのためには "362 日" をどう過ごすかでしかないのでがんばっていきたいです。

あ、でも去年登壇した成果としてクロージングキーノートに一瞬出演できたのはうれしかったです。

KeebKaigi 2023

話が前後しますが Day 0 には KeebKaigi 2023 に参加しました。皆さんのこだわりがつまったキーボードを眺めているだけでも胸熱だったんですけど、その中で僕の今の希望にばっちりハマるキーボードが展示されていて、しかもそのキーボード遊舎工房さんも展示されていて、思わず買っちゃいましたね、、、こいつを。

[Pre-order] cocot46plusshop.yushakobo.jp

組み立てサービスがない商品なのでこれを機に頑なにやってこなかった半田付けを頑張るか、、

特に Aaron さんのトークでは顕著に感じましたけど、キーボードという枠組みを超えたチャレンジがあるというか、僕が想像してた KeebKaigi とは全然違ったんですよね。もちろんいい意味で。愛に溢れたキーボード自慢的なものを想像してたんですけどキーボードの可能性みたいなものを感じられたというか。ただ文字入力するだけの目的ではない "キーボード" の世界を見れたことが収穫でした。僕はまだ沼に近づいてさえいなかった!

スポンサー&ノベルティ

会社でやったことですけど個人的に感想だけ書いておきます。

Coffeehouse Sponsor

受付時に配布されたお食事バウチャーにお世話になった方も多いと思いますが、その対象店舗のうちカフェに分類される店舗は弊社の提供でお送りしておりました。

blog.agile.esm.co.jp

スポンサーの着想はよかったと自負しているのですが、事前の広報だったり会期中のアナウンスがうまく機能していなくて、ちょっと話題性に欠ける感じになってしまったのが反省点かなー。でも店舗に弊社のロゴ入りステッカーが貼られているのはうれしかった。

一方で、一部の方からは「コーヒー好きなのでめっちゃいいスポンサーでありがたいです!」とか「モーニングに Rubyist がめっちゃ集まっていてふーがさんがやりたかったこと実現できてましたよ」などのフィードバックをいただけて感無量でした。ご活用いただいた皆様ありがとうございます。そしてこういうフィードバックは本人に届くとめちゃくちゃうれしいことが改めてわかったので、伝えられるフィードバックは伝えていこう(推しは推せるうちに推す、的な)と思ったのでした。

Ruby メソッドかるた

まずはかるたを受け取ってくださった皆さん、遊んでくださった皆さん、ありがとうございました。個人的には予想以上の反響があってブースがない状況ながらも 3 日目早々に在庫切れになったのには驚きました(多少余ると思っていた)。
かの有名なやんちゃハウスでは会期中に遊んでもらっていたり、やんちゃクラブ内でも言及していただいたきました。

youtu.be

今回のノベルティ関連で台風の目になったと言っても良いんじゃないでしょうか。他にもたくさん遊んでみたツイートを観測しておりうれしい気持ちです。

旗振りを率先してやってくれた同僚の @haruguchi , @ima1zumi に感謝👏 かるたにするメソッドは弊社メンバーで協力して出し合ったものなので、どの札を誰が考えたのか当ててみてくださいw

まつもとさんには僭越ながら僕がお渡ししました。

余談

体力

昨年の RubyKaigi では疲れ果てて帰る前に観光する体力が残っていませんでした。せっかく来たのに観光しないのか…と思いつつまっすぐ帰ることに。
今年はそれが嫌で 1 月くらいからトレーニングを始めて体づくりをしていったのですが、そのおかげか返ってきた今も疲れはかなり少なめで、もう一周 RubyKaigi があっても楽しめそうなくらいには体力が残っています。
来年は那覇での開催ということでマリンスポーツをはじめとしたアクティビティを楽しむ方も多いのではと思います。RubyKaigi に向けた(別に向けなくてもいいが)トレーニング、おすすめです。筋肉はすべてを解決する、というのは本当だったんだ…

下見

会期の 1 ヶ月弱前くらいにスポンサー周りの下見として 1 泊 2 日で松本に行っていたのですが、これほんと行ってよかったなぁと会期中にめっちゃ思いました。(松田さんが同行してくださっていたのはかなり大きいですが)街の解像度が高くなっていたおかげで Rubyist に街の案内ができたり、同僚に事前に情報を伝えられたりできたので。会期中の話題になるし "交流" の側面でかなりのアドバンテージがあって RubyKaigi をより一層楽しめたと感じています。
みんな下見に行こう!!!

おわり

今回特に思ったのは「フィードバックは伝えられる限り伝えていこう」ということでした。自分自身が言われてうれしかったし、僕が伝える側のときは伝えた相手がうれしそうにしてくれるからです。それがモチベーションになればより良いアウトプットに繋がるでしょうし良いループが生まれるんじゃないかなと思いました。気の利いたことは言わなくても一言「ありがとう」だけでも十分なフィードバックです。だから僕は今後もこのムーブを続けていくと決めました。

そして RubyKaigi は登壇した方がより一層楽しめるのだとわかったので来年も再来年もその先も登壇は常に狙っていきたい。正しくは "362日" の先に地続きであるものだと思うので "362日の Rubyist" としてやっていくぞ、という気持ちです。

最後になりますがお話ししてくださった皆さん、連れて行ってくれた弊社、送り出してくれたチームメンバー、そして何より RubyKaigi チームの皆さん本当にありがとうございました。特に RubyKaigi チームの皆さんの尽力のおかげで楽しい 3 日間(5 日間?)を過ごすことができました。お疲れ様でした!

来年の沖縄も絶対行くぞ!!!また春に会いましょう👋

RBS の CLI コマンドをざっくりながめる

こんにちは、ふーが です。
この記事はぼくの勤務先である永和システムマネジメントで開催している ESM Advent Calendar 2022 の 4 日目の記事です。

さて、rbsリポジトリを眺めていたら、README に使ったことのないコマンドがいくつも書いてあることに気が付きました。

$ rbs version
$ rbs list
$ rbs ancestors ::Object
$ rbs methods ::Object
$ rbs method Object then

github.com

とても今更ですがそれぞれどんなコマンドなのか見てみます。
rbs のバージョンは 2.8.1 で試します。

$ rbs -v
rbs 2.8.1

rbs version

実行結果:

$ rbs version
rbs 2.8.1

これはそのまんまですね。バージョン番号が出力されます。

RBS::CLI#run に定義されていて、実装はこのあたりです。 github.com

rbs list

実行結果:

$ rbs list
::Array (class)
::BasicObject (class)
::Binding (class)
::Class (class)
::Comparable (module)
::Complex (class)
::Dir (class)
.
.
()

型定義されている Class, Module, Interface が出力されます。

引数として --class のように指定ができて、指定されたもののみ出力されるようにできます。 例えば以下なら、型定義のうち Class と Module のみ出力されるようにする、といった具合です。

# Interface は出力されない
$ rbs list --class --module

rbs ancestors

実行結果:

$ rbs ancestors ::Object
::Object
::Kernel
::BasicObject

引数で指定した Class, Module の(自身を含む)祖先が出力されます。
オプションとして --singleton , --instance があり、デフォルトでは --instance を指定したことになります。 --singleton を指定すると singleton クラスを含んだ結果が出力されます。

$ rbs ancestors --singleton ::Object
singleton(::Object)
singleton(::BasicObject)
::Class
::Module
::Object
::Kernel
::BasicObject

実装はこの辺からです。 github.com

rbs methods

実行結果:

$ rbs methods ::Object
! (public)
!= (public)
!~ (public)
<=> (public)
== (public)
=== (public)
=~ (public)
Array (private)
.
.
()

引数で指定した Class, Module のメソッドの一覧を可視性付きで出力します。
オプションの --instance--singleton については rbs ancestors コマンドと同じ意味合いのようですが、こちらのコマンドには --inherit, --no-inherit というオプションもあります。 --inherit オプションは super class や mix-in した Module で定義されているメソッドについても出力します。これはデフォルトの動作です。 --no-inherit オプションはその逆で、それらのメソッドについては出力しません。

実装はこの辺からです。 github.com

rbs method

実行結果:

$ rbs method String to_i
::String#to_i
  defined_in: ::String
  implementation: ::String
  accessibility: public
  types:
      (?::int base) -> ::Integer

第一引数に Class (Module)、第二引数にメソッド名を渡すことで、そのメソッドの型定義情報が出力されます。定義元や可視性、型情報などが出力されています。 こちらもオプションは --instance--singleton があり、--instance がデフォルトです。

実装はこの辺からです。 github.com

おわりに

クラスやメソッドの型定義を出力できるコマンド類があることを知り「これを使って型と実装の乖離を検知できたりしないかな」と思ったのですが、実装を読んでみると標準ライブラリと gem の型定義のみを読み込んで出力しているようでした(たぶん。違ったら教えてください)。つまり自分で定義した sig/ 以下にあるような型定義は対象外っぽい…。

COMMANDS の配列 を見る限り他にもまだコマンドがあるようなので、折を見てそちらもどんなコマンドなのかを追ってみたいと思います。