diary

I like Hatena Star with a text selection.

2020-01-02

ストロベリー・フィールズをもう一度、を読んだ。めちゃくちゃ良すぎる。 どうでもいいけど主人公がいちご好きだからいちごのスイーツを買ってきてしまった。こういうところ影響されやすくてミーハーだと思う。


github.com

今日のruby-signature。rbs prototype rbコマンドでよく分からんkwrestが出力されていたので直した。 最初「あれ、Rubyって定義してないkeywordを渡したら無視するんだっけ?」などと深読みしていたけど、そうではなかった。

これで6500 -> 6000ぐらいまで警告が減った。


今日もKibelaのPRを眺めてrubocop-typedのネタを探していたけど、あまりいいものがなかった。 昨日から300個ぐらいPRを眺めていたっぽい。 これはつまりPRを300回解析しても役立たないものしか作れないだろうということにも捉えられて、結構しんどい。うーむ。

多分、もうちょっと経験が浅い人が書いたPRを見ていく必要があるのだろうなあ。

PRを見ていてもあまり収穫はなさそうだったので、方針を変えて、RuboCopでCloseされたfeature requestを眺めたりしていた。

https://github.com/rubocop-hq/rubocop/issues?q=is%3Aclosed+new+cop+is%3Aissue+-label%3Abug+label%3A%22feature+request%22

hash#[]の代わりにHash#digを使うようにするCopというのはありじゃないかなあ。 https://github.com/rubocop-hq/rubocop/issues/5332


rubocop-rubycw の v0.1.4 をリリースした。

https://github.com/rubocop-hq/rubocop-rubycw/commit/1d68d264a17102e42ab81ef9dce12398d181f208

-eオプションの違いについての修正だけ。znzさんからもらっていたPRをマージしてリリースした。

2020-01-01

Shadow of Warをやっているのだけど、ヘルムとかイシルドゥアって原作でもあんな感じだっけ。


rubocop-typedのネタを考えている。

https://github.com/pocke/rubocop-typed/issues/2

とりあえず「Rails アンチパターン」でググって出てきた記事をひたすら眺めているけど、設計よりの話が多くて、求めているものとちょっと違う。

社のGitHubリポジトリのPRをひたすら眺めているのをやっているけど、あんまりいいアイディアは出なくてむずかしい。 どっから手を付けていこうかな。 冬休みももう後半(だよね?)なので、なんとかしたい。


今日はあんまりコードを書かなくて、ruby-signatureへのPRは1件だけ。 これも昨日書いたコードで、今日はPRの本文を書いただけだけど。

github.com


github.com

ruremaのPRをあさっていたら、sho-hさんの未完了のPRがあったので拾ったりしていた。


昨日あたりから星屑ネバーランドガーデンを読んでいた。めっちゃ好き。

2019-12-31

gemが潰したはずのRubyの警告を吐いてて「きさま、倒したはずじゃ…?!」と思ったら、rbenvでそのディレクトリで管理されているRubyのバージョンで、警告が直ったgemをインストールしていないだけだった。


今日も型を見ている。

github.com

昨日Issueにした、キーワードと同名の引数名を定義できない問題を、エスケープを入れることで直した。

これを実装していたら、キーワードを末尾に含むようなメソッド名が不必要にescapeされているのに気がついて直した。

class C
  # "out"がキーワードなので、それを末尾に含む"timeout"までエスケープされてしまう
  def `timeout`: () -> Integer
end

github.com

これめっちゃむずかった。 PRを見ると簡単そうに見えるのだけど、そもそもSteepがコケているというところから、「なぜか定義されていないはずのクラスをresolveできてしまっている」というのにたどり着いて、それを直すまでがかなり大変だった。


github.com

rbs prototype rbコマンドがclass << self構文をサポートしていなかったのでサポートした。

これはクラスメソッドとインスタンスメソッドで同名のメソッドを持っているクラスがあって、メソッドが重複していると怒られたので気がついた。

class C
  class << self
    def m() end
  end

  def m() end
end

上のクラス定義から型定義を生成しようとすると次のようになってしまう

class C
  def m: () -> untyped

  def m: () -> untyped
end

このPRによって次のようになる

class C
  def self.m: () -> untyped

  def m: () -> untyped
end

Kibelaに型を入れるのは、つぎのような感じですすんでいる

  • Rubyコードから型のprototypeを生成
    • untypedだらけの型定義が手に入る
    • クラス名やメソッド名の重複があったりするので適当に倒していく
  • ActiveRecordの持っている情報を使って、カラムをattr_accessorの型として定義する
    • これはprototypeで生成したやつのextensionとして生成している。
  • Steepを走らせてはバグを潰していく
    • stack overflow https://github.com/ruby/ruby-signature/pull/158
      • これはなかなか高難易度だった
    • 今はcache周りのエラーを倒している…
      • とりあえずパッチはできた。正しいのかよくわからないけど、明日きれいにしてPull Requestにする
    • あとは知らない型があると落ちるので、それを適当に無の型をつけていく。
      • class ActionController::Base endみたいなのをひたすら書いていく
      • これはライブラリの型を手に入れればいい感じになるはずですね

という感じ。

なんと頑張った結果KibelaRails appでSteepが例外を吐かずに完走するところまで持っていくことができた。じぶんえらい!

実行に6分ぐらいかかっていて、型エラーは6500個ぐらい出ている。まあこれは型が全然足りていないから仕方がない。


るりまレビュー会やった

https://rurema-review.connpass.com/event/160758/

S-H-GAMELINKSさんが出しているCのサンプルコード、良い取り組みだと思うのだけど、Cが全然わからないのでレビューがむずかしい。 Cが分かる人に任せたい。(放置され続けたらレビューします…)

github.com

るりまのRuby 2.7変更対応は、誰かがやらないと誰もやらないかなと思って1つPRを出してみた。🐧 簡単なやつも多いと思うので、取り組んでもらえるとうれしいです。


pocke.hatenablog.com

これを読んで実際に使ってくれる人がvim-jpまわりでちょこちょこいて嬉しい。

2019-12-30

github.com

Steepを試しにKibelaに突っ込んでいて、エラーが標準出力に出ていて邪魔だったので標準エラー出力に出すようにしてみた。


最低限クラスがあることがrbsで書かれていないと、部分的に型を書いたとしてもSteepは使い物にならなさそうなので、まずは全部のクラスの型を生成する必要がありそう。 これはruby-signatureにある適当なコマンドでいけるかな。

# Userクラスの型定義
#   class User
#     def self.find: (Integer) -> instnace
#     def name: () -> String
#   end

user = User.find(1)
user.name # これはok
user.full_name # これはNoMethodErrorがちゃんと見つかる


class UsersController
  def show
    # Userクラスがanyにfallbackしてしまう
    # 当然user変数もanyにfallbackする
    user = User.find(1) 
    user.name      # anyに対するメソッド呼び出しなのでチェックが無
    user.full_name # これもanyに対するメソッド呼び出しなのでチェックが無
  end
end

つまりなんらかのクラス定義の中にある定数参照は、外側のクラス定義が型として定義されていなければすべてanyにfallbackするので、解析が無になる。


github.com

たしかに🦀と思ったのでrevertした。勉強になった。


github.com

rbsコマンドのヘルプメッセージをいい感じにした。OptionParserではbannerに文字列をセットするといい感じにできる。


github.com

rbs prototype rbコマンドがうまく動かないので直している。 想定してないnode (今回は引数なしのFCALLとyield)にぶつかったときはまあ直せばいいので簡単。

syntax errorのコードを吐いているのがむずかしくて、typeキーワード引数があると死ぬ。というか普通の引数でも死ぬ。

class X
  # ダメ
  #
  # def foo: (type: untyped type) -> untyped
  def foo(type:)
  end

  # これもダメ
  #
  # def bar: (untyped type) -> untyped
  def bar(type)
  end
end

上のクラス定義はコメントのようにrbsが生成されるけど、rbsではtypeは予約語であり、かつvar_name_opt(うしろのtype)では予約語は許されていないので死ぬ。 keyword_name(まえのtype)では予約語が許されているからこちらはokぽい。

どうするのがいいのだろう。とりあえず次の2つは思いつく。

  • var_name_opt予約語を許す
    • とりあえずconflictを増やさず実現はできそう。
  • メソッド名みたいにbacktickでescapeできるようにする

rbs prototype rbコマンドが生成するrbsの名前を適当にunderscoreとかつけてごまかすこともできるけど、rbsを手書きする時にtypeって書きたい人もいるだろうし、書けるようになっていたほうが便利な気がするなあ。

……ということをIssueに書いた。

github.com


hanachinさんがruby-signatureに出していたPRをレビューしてた。

https://github.com/ruby/ruby-signature/pull/150#discussion_r362002475 これは型検査器がメソッドのオーバーロードを見る時に定義順で見ることをruby-signatureが前提として置いていいのか、というのが気になった。 前提としていいのならこの型定義でいいんだけど(便利)、前提にするべきでないなら壊れる可能性があるからやめたほうがよさそう。

https://github.com/ruby/ruby-signature/pull/149#discussion_r361998221 もっと狭い型を返せそうだったからコメントした


github.com

ruby_hl_lvar.vim でmassignが壊れているのを直してくれているPR。 そのうちレビューしよう…。

2019-12-29

オンライン型会議してた。

rbsfmtをWriterに寄せつつ実装していきたい。


github.com

ruby-signatureのWriterで空行を保持するようにした。これでフォーマッタに少し近づく。

github.com

hashメソッドがいくつかバグっていたので直した。 ついでにリファクタリングをしてだいぶコードを消した。


github.com

検索してるりまがヒットした時に、頭に「Instance method」ってきているのが邪魔だなーと思ってIssueを立てた。


Vimでpopup windowを使って右端にコード片を表示するプラグインを作っている。 とりあえずdotfilesの中に.vim/autoloadディレクトリを掘ってそこにコードを突っ込んでいる。このスタイル楽で良いな

2019-12-28

今年の英会話レッスンを納めた。 お金がかかるから来年2月で英会話をやめるし、オンライン英会話とかをはじめようかなあ。 何かしら英語を話す習慣がないと忘れそう。


ruby-signatureでString literal typeでString#undumpを使えるのでは。と思ったけど、"あ"みたいなnon asciiなliteralが書かれているとundumpが死ぬからボツ。


github.com

Vimプラグインを作ろうかと思ってヘルプを読んでいたら誤訳を見つけたのでPRを出した。


popupとtextpropを使ったVimプラグインを作っている。

2019-12-27

渋谷Vimランチをした。🍛 時々社外の人とランチ行くの良いですね。Rubyistともやりたい。

引きこもり的には目黒でやりたいけど、まあ渋谷までたまには出ていくのも良いかもしれない。

問題は、私が旗振り役をやりたくないというところにあって、多分一生やらない


今日は仕事納めで、ゆるゆると仕事をしていた。 社で出しているOSSのCIでRuby 2.7を使うようにしたり(Travis CIは2.7がきてた)、OSSにコメントしたり、だいたいOSSを触っていた。


rbsfmtが、ruby-signatureのテストを壊さないぐらいにはまともなコードを吐くようになった。 まだ課題は沢山残っている。

  • 長すぎる行を丁度いいところで改行する機能
    • どこを改行すると自然なのか
      • 構文的にはどこでも改行できるのだけど、人間的にはどこでもは改行したくない
    • 改行した時にtrailing commaを入れたい
  • コメントの対応
    • 今は雑にしかコメントを扱っていないので、コメントが消えたりする。
    • ちょっと難しいけど、意味不明な位置にコメントを書けないことにすれば、わりといけるのではと思っている。
# このコードに対して、
def foo: () -> void

# 次のようにコメントを書ける
def
  # ここにコメントを書ける
  foo
  # ここにコメントを書ける
  :
  # ここにコメントを書ける
  (
  # ここにコメントを書ける
  )
  # ここにコメントを書ける
  ->
  # ここにコメントを書ける
  void

soutaroさんにwriterというのがあることを教えてもらった。車輪の再発明をしていたっぽい。まあ楽しかったからいいか。 https://github.com/ruby/ruby-signature/blob/967a50fe5cfbd2de31f865445821c972852f8b1f/lib/ruby/signature/writer.rb

writerベースで書き直そうかな。smoke testがあるからそれを適用してみたら、writerのバグをいくつか見つけたので直した。

github.com

いい感じに改行をいれることを考えると、Writerの実装のままだとつらそう。