ruby-type-profilerとRBS試してみた
rubyのバージョンは2.7.1
Ruby Type ProfilerをREADMEの通りにSetup
code:sh
git submodule init
bundle install
したらrbsがないって怒られたので、gem install rbsしてから改めてbundleしたら通った code:sh
ruby exe/type-profiler /Users/zakuni/dev/weather-report/lib/weather-report/day.rb
# Classes
class WeatherReport::Day
@forecast : untyped
@temperature : ()?
attr_reader date : untyped
attr_reader telop : untyped
attr_reader temperature_min : bot
attr_reader temperature_max : ()?
def date : -> untyped
def telop : -> untyped
def temperature_min : -> ()?
def temperature_max : -> ()?
def initialize : (untyped, untyped) -> untyped
def rain? : -> bool
def snow? : -> bool
def umbrella? : -> bool
def to_h : -> {String=>()?}
def forecast : (untyped, untyped) -> untyped
end
なるほど面白い。untypedだらけや
別のファイルでも
code:sh
ruby exe/type-profiler /Users/zakuni/dev/weather-report/lib/weather-report/weather.rb
# Classes
class WeatherReport::Weather
@uri : untyped
@forecasts : untyped
@response : untyped
attr_reader today : untyped
attr_reader tomorrow : untyped
attr_reader day_after_tomorrow : untyped
def today : -> untyped
def tomorrow : -> untyped
def day_after_tomorrow : -> untyped
def initialize : (untyped) -> untyped
def self.request_cityid : (untyped) -> untyped
def self.parse_proxy : (untyped) -> untyped
def link : -> untyped
def to_h : -> {String=>untyped}
def forecasts : -> untyped
def read : -> untyped
end
さらに試しに、rbsも書き足してみる
code:weather.rbs
module WeatherReport
class Weather
def self.request_cityid: (String) -> String
def link : -> String
end
end
最初、type-profilerが出力したclass WeatherReport::Weatherで書いたら動かなかったのでちゃんとmoduleはmoduleで指定
使わなかったけどrbs prototypeコマンドってのもある
書き足したrbsを指定しつつ再トライ
code:sh
ruby exe/type-profiler /Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs /Users/zakuni/dev/weather-report/lib/weather-report/weather.rb
#<RBS::AST::Declarations::Class:0x00007fd3dbd85098 @name=#<RBS::TypeName:0x00007fd3dbd875f0 @namespace=#<RBS::Namespace:0x00007fd3dbd87640 @path=:WeatherReport, @absolute=true>, @name=:Weather, @kind=:class>, @type_params=#<RBS::AST::Declarations::ModuleTypeParams:0x00007fd3dbce4fd0 @params=[]>, @super_class=nil, @members=[#<RBS::AST::Members::MethodDefinition:0x00007fd3dbd85390 @name=:request_cityid, @kind=:singleton, @types=[#<RBS::MethodType:0x00007fd3dbd853e0 @type_params=[], @type=#<RBS::Types::Function:0x00007fd3dbd85458 @return_type=#<RBS::Types::ClassInstance:0x00007fd3dbd855c0 @name=#<RBS::TypeName:0x00007fd3dbd859f8 @namespace=#<RBS::Namespace:0x00007fd3dbd85a70 @path=[], @absolute=true>, @name=:String, @kind=:class>, @args=[], @location=#<RBS::Location:560 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=78...84, source='String', start_line=3, start_column=41>>, @required_positionals=[#<RBS::Types::Function::Param:0x00007fd3dbd857f0 @type=#<RBS::Types::ClassInstance:0x00007fd3dbd858b8 @name=#<RBS::TypeName:0x00007fd3dbd859f8 @namespace=#<RBS::Namespace:0x00007fd3dbd85a70 @path=[], @absolute=true>, @name=:String, @kind=:class>, @args=[], @location=#<RBS::Location:580 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=67...73, source='String', start_line=3, start_column=30>>, @name=nil>], @optional_positionals=[], @rest_positionals=nil, @trailing_positionals=[], @required_keywords={}, @optional_keywords={}, @rest_keywords=nil>, @block=nil, @location=#<RBS::Location:600 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=66...84, source='(String) -> String', start_line=3, start_column=29>>], @annotations=[], @location=#<RBS::Location:620 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=41...84, source='def self.request_cityid: (String) -> String', start_line=3, start_column=4>, @comment=nil, @overload=false>, #<RBS::AST::Members::MethodDefinition:0x00007fd3dbd850e8 @name=:link, @kind=:instance, @types=[#<RBS::MethodType:0x00007fd3dbd85138 @type_params=[], @type=#<RBS::Types::Function:0x00007fd3dbd85188 @return_type=#<RBS::Types::ClassInstance:0x00007fd3dbd851d8 @name=#<RBS::TypeName:0x00007fd3dbd859f8 @namespace=#<RBS::Namespace:0x00007fd3dbd85a70 @path=[], @absolute=true>, @name=:String, @kind=:class>, @args=[], @location=#<RBS::Location:640 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=103...109, source='String', start_line=4, start_column=18>>, @required_positionals=[], @optional_positionals=[], @rest_positionals=nil, @trailing_positionals=[], @required_keywords={}, @optional_keywords={}, @rest_keywords=nil>, @block=nil, @location=#<RBS::Location:660 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=100...109, source='-> String', start_line=4, start_column=15>>], @annotations=[], @location=#<RBS::Location:680 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=89...109, source='def link : -> String', start_line=4, start_column=4>, @comment=nil, @overload=false>], @annotations=[], @location=#<RBS::Location:700 @buffer=/Users/zakuni/dev/weather-report/lib/weather-report/weather.rbs, @pos=23...115, source='class Weather ', start_line=2, start_column=2>, @comment=nil>
# Classes
class WeatherReport::Weather
self.@response : untyped
@uri : untyped
@forecasts : untyped
@response : untyped
attr_reader today : untyped
attr_reader tomorrow : untyped
attr_reader day_after_tomorrow : untyped
# def self.request_cityid : (String) -> String
# def link : -> String
def self.request_cityid : (untyped) -> untyped
def today : -> untyped
def tomorrow : -> untyped
def day_after_tomorrow : -> untyped
def initialize : (untyped) -> untyped
def self.parse_proxy : (untyped) -> untyped
def to_h : -> {String=>String}
def forecasts : -> untyped
def read : -> untyped
end
なんかめちゃくちゃ出力が増えたけど動いたし、指定した通りになってる
あと、rbs書き足したメソッドのところには#で印がついた
おまけでsteepでも型検査してみたけど、型を書いてないこと自体を咎められる感じだった 感想
面白かったです
エディタとかIDEで使えるようになってこそ真価を発揮する感じはする
なるべく型情報書きたくないマンとしては、ruby-type-profilerに頑張ってもらって、最低限だけrbsに書き足していくってアプローチがやはり良いのであろう
rdocで引数とか返り値の型を書いてたのであれば、rbsで書く方が静的解析の恩恵得られてメリットありそう