스타일리시한 Rails 개발(2021/01/07)
전제 지식
루비의 유형을 포착하지 못한 주변 사람들은 이 근처를 읽어보는 게 좋을 것 같아요.
rbs,type,steep
참고 사이트는 아래와 같다(이하 내용만 하고 상세한 내용은 생략한다)
차리다
$ ruby -v
# ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
$ gem install steep
실제
다음의 실현을 토대로 설명한다.
def plus(x, y)
x + y
end
p plus(1, 2)
먼저 typeprof
를 통해 유형 정보로 rbs 파일을 생성한다.$ typeprof app.rb -o sig/app.rbs
rbs의 내용 현황은 다음과 같다.# Revealed types
# app.rb:5 #=> Integer
# Classes
class Object
private
def plus: (Integer x, Integer y) -> Integer
end
다음에 steep init
명령을 사용할 때 절차 파일을 생성하기 때문에 다음과 같이 이 명령을 편집합니다.Stepfile의 기법을 자세히 설명하는 페이지를 찾지 못했지만 Pocke의 설명은 다음과 같다.
target :lib do
# rbsファイルがあるディレクトリ の指定
signature "sig"
# 解析したいrubyコードのディレクトリ/ファイル
check "app.rb"
# (以下、今は不要だが一旦載せておく)
# gem_rbs 内の gems ディレクトリへのパスを指定
# repo_path "gem_rbs/gems"
# rbs gem, gem_rbs からrequireしたいライブラリ名を指定
# library 'pathname'
end
까지 금형 검사를 할 수 있다.$ steep check
# エラーがなければ、何も表示されない
plus
에 전달되는 매개 변수를 문자열 등으로 설정할 때 검사하는 중 오류가 발생했습니다.$ steep check
# app.rb:5:10: ArgumentTypeMismatch: receiver=::Object, expected=::Integer, actual=::String ("a")
vscode로 보완해 볼게요.
vscode의 extensions로 steep 설치를 검색하면 OK.
문서와 같이 다음을 주의하십시오.이하가 적절하게 진행되지 않으면 아무것도 검사하지 않을 것이다.
bundle exec steep langserver
를 실행하고 유형 검사를 진행하기 때문에 Gemfile이 명령을 실행해야 합니다설치 후 편집기에서 보완 검사를 진행합니다!
배열 조작에도 보충 작용이 있다.
rbs_rails 테스트
참고 사이트는 아래와 같다(이하 내용만 하고 상세한 내용은 생략한다)
우선 절차에 따라 제작된 창고도 미리 공개한다.
생성 rbs
프로그램은 참고 사이트를 참조하세요.다음은 만재점(2021년 1월 7일까지.rbs rails 버전 0.8.0)
rails new rails_with_rbs_rails_sample --api
이후bin/rake rbs_rails:all
각종 오류가 발생할 수 있으므로 필요하지 않은 라이브러리를 잠시 무시bundle exec rbs -rlogger -rpathname -rmutex_m -rdate --repo=gem_rbs/gems -ractivesupport -ractionpack -ractivejob -ractivemodel -ractionview -ractiverecord -rrailties -I sig validate
를 시도할 때 다음과 같은 오류가 발생했습니다./Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/rbs-1.0.0/stdlib/logger/0/log_device.rbs:3:4...3:24: Could not find mixin: MonitorMixin (RBS::NoMixinFoundError)
후속 단계가 적절하게 이동하기 때문에 잠시 무시합니다.steep의 집행
$ bundle exec steep check
app/mailers/application_mailer.rb:2:2: NoMethodError: type=singleton(::Object), method=default (default from: '[email protected]')
app/mailers/application_mailer.rb:3:2: NoMethodError: type=singleton(::Object), method=layout (layout 'mailer')
rails 디렉터리에 대해 유형 검사를 할 수 있습니다.의외의 오류가 적습니다. 대단합니다. clap:지금까지 액션이었습니다.메일의 형식 정의가 부족한 오류입니까?
스스로 모델을 적절하게 생성한다.
$ bin/rails generate model post title:string body:text
$ bin/rails db:migrate
생성 단계에서 Post 클래스에 해당하는 rbs 파일이 없기 때문에 유형 검사를 하지 않습니다.rbs를 다시 생성합니다.겸사겸사rails는 실제로 rails를 실행하여 rbs 파일을 생성하기 때문에, 예를 들어 rails에서 MySQL을 사용하면 mysql도 미리 시작해야 한다.
$ bin/rake rbs_rails:all
Post 클래스에 적절히 장착class Post < ApplicationRecord
def foo
title.split(',')
end
end
title은nilable이므로 오류가 발생했습니다!느낌이 좋다.vscode의steep extension에서 이 유형의 정보를 반영하기 위해서는 매번 restart가 필요하기 때문에 vscode의 명령 팔레트(Shift+Cmd+P)에서 진행
Steep: Restart all
합니다.그나저나
title&.split
처럼 쓰면 오류를 방지할 수 있지만 vscode의 보완이라면 스트링형 방법은 후보가 되지 않아 사용하기 어렵다.디렉터 설치 여부도 확인
$ bundle exec steep check
# ...mailerのエラーは省略
app/models/post.rb:3:4: NoMethodError: type=(::String | nil), method=split (title.split(','))
유형 정의 추가
그 전에
rbs_rails
에서 자동으로 생성된 유형 정의만 사용할 수 있다. 예를 들어 상기Post#foo
와 같은 자제적인 방법은 스스로 유형을 추가해야 한다.우선, 블로그에 소개된 바와 같이
rbs prototype
로 만들어 보세요.class PostsController < ApplicationController
def show
post = Post.last
{
title: post.title # 型が補完されている
}
end
end
# サンプル実装
class Post < ApplicationRecord
def foo
[1].map { |x| x + 1 }
end
def bar
title
end
end
의 출력 결과는 다음과 같다.프로타입의 이름과 같이 자신의 진행형 정의를 바탕으로 원형을 생성할 수 있다(=반환값은 단순한 상황을 제외하고는untyped이다).$ bundle exec rbs prototype rb app/models/**/*.rb > sig/models.rbs
type proof도 마찬가지로 다음과 같이 해봤습니다.foo 첨부 모형.# sig/models-prototype.rbs
class ApplicationRecord < ActiveRecord::Base
end
class Post < ApplicationRecord
def foo: () -> untyped
def bar: () -> untyped
end
$ typeprof app/models/**/*.rb -o sig/models.rbs
Foo#bar
사용Foo#title
하기 때문에 typeproof에서 타이틀이 적힌 유형 정의sig/rbs_rails/app/models/post.rbs
를 참조할 수 있었으면 좋겠지만 이 방법을 알 수 없습니다.(2021/01/10 추기) type proof의 문서에는 일반적으로 bow:
다음은 가능하지만 현재 상태라면 typeproof의 오류가 됩니다.(또한, rbs 파일을 지정하는 데 더 좋은 느낌을 줄 수 있다)
# sig/models-typeprof.rbs
# Classes
class ApplicationRecord
end
class Post < ApplicationRecord
def foo: -> Array[Integer]
def bar: -> untyped
end
issue를 미리 세웠다.일단 자신의 힘으로 바를 정의하면 유형 검사를 문제없이 진행할 수 있기 때문에 계속해서 진행한다.
실제 Rails 애플리케이션에
운용 중인 rails 응용 프로그램에서 상술한 절차를 실행해 보세요(절차 생략).
다음 오류입니다.
$ typeprof gem_rbs/gems/**/*.rbs sig/rbs_rails**/*.rbs app/models/post.rb -o sig/post.rbs
/Users/foo/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/typeprof-0.11.0/lib/typeprof/import.rb:262:in `each_class_decl': undefined method `decls' for nil:NilClass (NoMethodError)
잘못된 이름처럼 정의가 중복된 것 같습니다.코드를 보면 엔움과 scope의 이중 방법으로 정의된 코드 수정이 있기 때문입니다.이런 식으로 검사하는 건 어려워요. (중복 정의 같은 건 적어요.) (말하면서 하는 얼굴)수정 후 다시 금형 검사를 진행하면 대량의 오류가 발생할 수 있다.기본적으로 NoMethod Error이므로 type proof를 사용하여 직접 만드는 방법을 정의합니다.
rbs에서 다시 한 번 오류가 발생했습니다.
DuplicatedMethodDefinitionError
이 된다.원래부터 과속 금지설이 있었지만 어떻게든 필요할 때 이런 유형의 수정은 번거롭다.InvalidTypeApplicationError
잘 모르겠지만 에너마이트, 레인지 등으로 오류가 발생했다.이 근처의 대상은 읽히지 않았습니까?일시적 해소 처리.NoMethodError
이 있을 수 있지만 남은 오류를 대략적으로 분석하면 다음과 같다.총결산
드디어 루비도 유형 안전 개발의 미래를 볼 수 있게 됐다.실제 응용으로는 아직 도착하지 않았지만, 나는 계속 지원하고 싶다. (rbs 부근의 사람들에게 정말 고맙다.)
사용자로서 먼저 눈앞에 필요한 것은 다음과 같다.
Reference
이 문제에 관하여(스타일리시한 Rails 개발(2021/01/07)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/katsumanarisawa/articles/833b06ac80e1dc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)