質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

1回答

237閲覧

Rubyで型を導入したいですが、実現可能でしょうか?

baban

総合スコア19

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2024/04/07 12:29

編集2024/04/07 15:15

実現したいこと

そろそろRubyで型をプロジェクトに導入できないかな、と思って触ってみたのですが、
型触って2,3日しての質問です。

大分前に作ったgemに型推論でも入れようかと、
steepとrbsで軽く触ってみて、型定義ファイルを生成して色々回してみたのですが、型推論が上手くいかなかった所です

発生している問題・分からないこと

  • sendメソッドで移譲時
  • ENV["hoge"]などで環境変数を取った時

こういうのを変数で代入した時に型が消えてしまって、メソッドの返り値が分からなくなったあたりで型推論が出来なくなって作業が止まってしまいました。

該当のソースコード

# ActiveRecordを継承したクラスを動的に作成する # 以下のエラーが発生 # [error] Type `::Class` does not have method `table_name=` # │ Diagnostic ID: Ruby::NoMethod klass = Class.new(ActiveRecord::Base){ |o| o.table_name = table_name }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

軽く考えたのですが、変数代入時に、代入した変数の型をかけないと解決できなそうで、であれば型定義ファイルにメソッドの引数や返り値の型を書いてるだけでは解決しきれないように見えました。

Rubyのいずれかの型推論gemだと、ここの問題を解決して型推論を完結できるものはあるのでしょうか?

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2024/04/07 12:50

やったことを具体的に書いてください。ちなみにこのコメント欄に書くのではありません。質問文を編集して書いてください。
winterboum

2024/04/07 13:35

ruby3.0から導入された静的解析ですか?
ikedas

2024/04/07 21:49

「具体的に」とは、「それを読んだ他の人があなたがやったのと同じことを自分の環境で実行して問題を再現できるくらいに」という意味です。やったことを具体的に書いてください。
winterboum

2024/04/07 22:36

Class.new(ActiveRecord::Base){ |o| o.table_name = table_name } で `::Class` does not have method `table_name=` ってことは rbs の記述でとちったか steep の bugか。。との感。 ところで、 この例って sendメソッドで移譲時 ENV["hoge"]などで環境変数を取った時 の例ではないですね。
baban

2024/04/07 23:28

はい、直近で転んでいたところを書き足しただけですので、転んだ各所情報揃えてきます
guest

回答1

0

ベストアンサー

# ActiveRecordを継承したクラスを動的に作成する # 以下のエラーが発生 # [error] Type `::Class` does not have method `table_name=` # │ Diagnostic ID: Ruby::NoMethod klass = Class.new(ActiveRecord::Base){ |o| o.table_name = table_name }

これに関して、この記述に合わせたClassの型定義を書いてしまうと、全てのクラスに影響してしまうため現実的ではないかなと思います。そのためsteepのアノテーションコメントで誤魔化すくらいしかできることはないのではないかなと思いました。

# @type var o: ::Class < ActiveRecord::Base # @type var klass: ::Class < ActiveRecord::Base klass = Class.new(ActiveRecord::Base){ |o| o.table_name = table_name }

投稿2024/04/12 01:09

Mugheart

総合スコア2349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

baban

2024/04/25 14:33

お返事、おそくなりました。 元々はENVやsendに関して色々と引っかかっていましたが、以下のコードの様に `ENV`で取った値は、`to_s`や`to_i`で型変換したり メソッドが無い場合にsendで逃げたり、書き換えながら進んでいたのですが、上記の`CLass`で調べてみても継承させるところで回避できない所が出て、evalは回避不能って聞いていたし、他にも回避不能ケース色々あるんじゃないのか?と思って聞いてしまいました。 しかし、調査不足の早計で機嫌を損ねてしまったと思ってます。 一旦今回はここで質問を打ち切って、また情報を整えてから、出来ないケース一覧で質問させて頂く事にします。 ```ruby table_name = ENV[:table] klass = create_model(table_name) klass.respond_to?(:delete_all!) ? klass.delete_all! : klass.delete_all ``` ```ruby table_name = ENV[:table].to_s klass = create_model(table_name) klass.send(klass.respond_to?(:delete_all!) ? :delete_all! : :delete_all) ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問