rbs에 대응하여 Steep으로gem의 모델을 검사할 수 있습니다

며칠 전 루비3.0.0가 공개됐다.
다양한 기능이 추가됐지만 개인적으로도 정태적 해석을 해보고 싶어요.
금번
  • 직접 만든 유형 정보가 없는gem의 코드에 TypeProof 추론 유형 정보를 통해 rbs 파일을 만들어 gem에 첨부한다.
  • 이gem 옆에 있는 코드에 추가된 rbs 파일에 따라 Steep으로 형식 검사를 하십시오.
  • 나는 이 두 가지를 시험해 보고 싶다.

    용어


    상당히 새로운 단어가 있으면 혼란스럽기 쉽다.
    아래의 사이트는 쉽게 이해할 수 있다.
    https://techlife.cookpad.com/entry/2020/12/09/120454#:~:text = Step도 루비의 정적을 이뤘다.
    아까 사이트에서 인용한 내용.
    용어
    의향
    RBS
    루비의 유형 정보 설명용 언어
    TypeProf
    유형 정보가 없는 루비 코드에서 RBS를 출력하는 도구
    steep
    rbs 파일을 사용하여 루비에서 정적 형식을 가져올 수 있는 도구
    네.

    차리다


    이번에는 제가 최근에 Slack에 추가한 알파벳을 간단하게 입력하기 위한 그림입니다.
    slack_alphabetter
    나는 이런 누구에게나 유리한gem를 사용하고 싶다.

    gem 소개


    기본적으로 cli 도구를 사용합니다
    출력
    $ slack_alphabetter 'hello!'
    :alphabet-white-h::alphabet-white-e::alphabet-white-l::alphabet-white-l::alphabet-white-o::alphabet-white-exclamation:
    
    이므로 복사slack_alphabetter 'hello!' | pbcopy

    이렇게 전환된 게임은 매우 재미있다.
    이것은 아마 내부의 것이다
    require 'slack_alphabetter'
    puts SlackAlphabetter.convert(引数の文字列)
    
    의 느낌으로 움직이고 있다.
    현재 어떤 유형의 정보도 없기 때문에 임의의 유형의 대상을 전달할 수 있기 때문에 다음과 같은 오류가 발생할 수 있습니다.
    [2] pry(main)> SlackAlphabetter.convert(123)
    NoMethodError: undefined method `downcase' for 123:Integer
    from /Users/pocari/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/slack_alphabetter-0.1.4/lib/slack_alphabetter.rb:24:in `convert'
    
    이런 실수를 피하기 위해 슬랙알파벳에 추가형 정보를 steep으로 검사하면 잘못된 매개 변수가 전달된 부분을 검사할 수 있습니다!이것이 바로 이번 시도의 내용이다.

    gem측의 대응


    slack_알파버터의 경우 typeproof를 사용합니다. 유형 정보가 없는 루비 코드의 유형 정보를 추론하십시오.
    % typeprof lib/slack_alphabetter.rb
    # Classes
    class OptionParser
      alias set_banner banner=
      alias set_program_name program_name=
      alias set_summary_width summary_width=
      alias set_summary_indent summary_indent=
      alias to_s help
      alias def_option define
      alias def_head_option define_head
      alias def_tail_option define_tail
    
      class ParseError < RuntimeError
        alias to_s message
      end
    end
    
    module SlackAlphabetter
      def emoji: (untyped char, ?String color) -> String
      def self.emoji: (untyped char, ?String color) -> String
      def convert: (untyped str, ?String color) -> untyped
      def self.convert: (untyped str, ?String color) -> untyped
    
      class Error < StandardError
      end
    end
    
    module Shellwords
      alias shellwords shellsplit
      alias self.shellwords self.shellsplit
      alias self.split self.shellsplit
      alias self.escape self.shellescape
      alias self.join self.shelljoin
    end
    
    어떤 SlackAlphabetter.convert의 매개 변수는untyped(=무엇이든 되는 유형)이다.그리고 슬랙alphabbetter에는 리퀘어optparse의 정보도 출력되어 있다.
    전자의 untyped에 대해 typeproof의 구조는 실제적으로 유형 단계에서 루비 코드를 실행하고 실제 방법으로 전달된 매개 변수의 정보에 따라 추론하기 때문에 방법의 정의만 있어도 추론되지 않는다.
    후자의optparse에 대한 정의는 잘 모르겠습니다. 그렇습니까?
    한마디로 슬라이드 알파벳터의 정의만 사용하고 매개 변수의 정보를 수동으로 씁니다.또 SlackAlphabbetter 내부의 Error 레벨도 전혀 사용하지 않아 삭제해야 한다.
    따라서 다음과 같은 rbs 파일을 제작합니다.
    slack_alphabetter.rbs
    module SlackAlphabetter
      def emoji: (String char, ?String color) -> String
      def self.emoji: (String char, ?String color) -> String
      def convert: (String str, ?String color) -> String
      def self.convert: (String str, ?String color) -> String
    end
    

    rbs를 놓는 곳.


    rbs가 생겼어요. 이거gem의 어디에 두면 좋을까요?
    찾아보니 Steep 검사를 할 때gemのインストールディレクトリ/sig 폴더 이하의 rbs 파일을 읽을 수 있어서 sig/slack_alphabetter.rbs로 저장할 수 있습니다.
    gemファイルのルート
    + bin/
    + exe/
    + lib/
    + pkg/
    - sig/
        slack_alphabetter.rbs
    + spec/
      Gemfile
      Gemfile.lock
      LICENSE.txt
      Rakefile
      README.md
      slack_alphabetter.gemspec
    
    이 상태에서gem가 발표한 것은 슬랙알파벳터 버전0.1.4입니다.

    gem 측면의 대응 사용하기


    이어서 gm의 한쪽, 슬랙을 사용합니다.알파버터와 스텝을 넣고 모델을 검사해 보세요.
    한 세트https://github.com/pocari/steep_testpush에서 하고 있습니다.
    우선 이번 대상 코드입니다.
    lib/main.rb
    require 'slack_alphabetter'
    
    puts SlackAlphabetter.convert('hoge')
    puts SlackAlphabetter.convert(123)
    
    첫 번째 convert 호출은 String에 맡기기 때문에 정상이고 두 번째는 Integer에 맡기는 호출 방식으로 유형 오류가 발생하기를 희망합니다.
    다음은 스텝 설정.
    steep은 실행하기 위해 Stepfile이 필요합니다. 이 곳에서 사용할 프로그램 라이브러리를 설정합니다.
    Steepfile
    target :lib do
      check "lib"
      library "slack_alphabetter"
    end
    
    check에서 검사 대상 루비 코드가 있는 디렉터리를 지정하고 library에서 형식 검사 대상으로 사용할 프로그램 라이브러리를 지정합니다.이렇게 하면 방금 gm 측에 추가된sig 디렉터리에 있는 rbs 파일을 사용하여 형식 검사를 할 수 있습니다.
    준비가 다 되었으니 Steep으로 모델을 검사해 보세요.
    $ bundle exec steep check
    lib/main.rb:4:30: ArgumentTypeMismatch: receiver=singleton(::SlackAlphabetter), expected=::String, actual=::Integer (123)
    
    오류가 발생하기를 바라는 Integer를 상대방에게 순조롭게 맡긴 줄만 ArgumentType Mismatch로 바뀌었다.

    총결산

  • gem에 유형 정보를 추가해 보았습니다.
  • 이gem의 한쪽을 사용하는 코드에 대해 유형 검사를 실시했다.
  • 이외에도 Steep도 lsp를 실현한 것 같다. 소원 편집기에서 루비 코드의 자동 보충 등도 실현되면 점점 더 쉽게 쓸 수 있을 것으로 기대된다.

    좋은 웹페이지 즐겨찾기