96475


以下のように記載している例がありますが、RBSでのinitializeが返す型は何がいいんでしょうか？  
そもそも何も返さないのでしょうか（voidなのでしょうか）？

例1:  
[Rubyで型チェック！動かして理解するRBS入門 〜サンプルコードでわかる！Ruby 3.0の主な新機能と変更点 Part
1〜](https://qiita.com/jnchito/items/bf8c6c2e1dd6cff05f4e)

>
[code]

>     def initialize : (String) -> void
>  
[/code]

例2:  
[【Ruby
3.0】RBSの生成方法を色々試してみるメモ](https://kure.hatenablog.jp/entry/2021/01/01/010415)

>
[code]

>     def initialize: (untyped num) -> untyped
>     def initialize: (Integer num) -> Integer
>  
[/code]

Hoge.new、したときにinitializeが呼ばれるのですから、返り値の型はHogeなんじゃないかと思ったのですが、newがHogeを返すのであって、initializeは初期化処理にすぎないので、initialize
自体は、voidを返すということでしょうか？

それとも、Rubyは最後に評価された値を暗黙的にreturnするので、最後に評価される式の型を書けばいいんでしょうか？（initializeの場合は、最後に評価された値が仮に
return
されたとしても、別にその評価された値を呼び出し側で使いたいわけでも、使えるわけでもなさそうなので、型の情報としては、だれもそんなことに興味を示さなさそうですが...
RBS的には返り値を書かないとダメ？）


CC BY-SA 4.0
2023-10-11T05:40:01.837
96467
2023-10-11T12:08:25.077
2023-10-11T06:10:18.100
3060
9008
question
ruby rbs
RBSでのinitializeが返す型は何を指定すべき？


Ruby では、 `#initialize` メソッドは `.new` メソッドによって内部的に呼び出されます。

リファレンスマニュアルには `.new` メソッドは次のように説明されています。

> new は Class#allocate でインスタンスを生成し、 Object#initialize で初期化を行います。  
>  <https://docs.ruby-lang.org/ja/latest/method/Class/i/new.html>

RBS はおそらくこの考えをベースとしているようで、 `#initialize` メソッドの返り値型は利用されません。  
ですので、 `-> void` であっても `-> Integer` であっても、型チェックには影響を与えません。

>
> それとも、Rubyは最後に評価された値を暗黙的にreturnするので、最後に評価される式の型を書けばいいんでしょうか？（initializeの場合は、最後に評価された値が仮に
> return
> されたとしても、別にその評価された値を呼び出し側で使いたいわけでも、使えるわけでもなさそうなので、型の情報としては、だれもそんなことに興味を示さなさそうですが...
> RBS的には返り値を書かないとダメ？）

Ruby で返り値の型を書く場合、「どういう値を返しているのか」ではなく「どういう値を "返したい" のか」という観点を持つとよさそうです。

仰る通り、Ruby では最後に評価した値を return していますが、たまたま最後の代入文が Integer だったからといって、その値を "返したい"
わけではないことってありますよね。  
`-> void` というのは「何かを返すかもしれないが、その返り値には意味がない」ことを表現します。  
前述通り、 `#initialize` メソッドは Ruby
の内部から呼び出されるメソッドで、返り値になにか意味のあるメソッドではありません。ですから、こうした場合は `-> void` を使うのが良さそうです。


CC BY-SA 4.0
2023-10-11T12:05:04.223
96474
2023-10-11T12:05:04.223
60084
96467
answer


はい、 `initialize` メソッドの返り値は単に捨てられて、使われることはありません。なので、「何を返しても良い」ということになります。

何を返しても良いのですから、別に `Integer` でも `bool` でも良いのですが、そうすると `initialize`
に最後に書いてある式によって、型エラーが発生することになります。

[code]

    class Hoge
      # initialize の型が (String) -> String だとすると
      def initialize(string)
        @string = string        # ← この行だけなら型エラーになりませんが、
        # @size = string.size   # ← この行を追加すると型エラーになる
      end
    end
    
[/code]

この「メソッドから何を返しても良い」という状況は、そこそこ頻繁に発生しますので、RBSでは専用の型を用意してあり、それが `void` です。

「RBSでの `initialize` の返り値の型は `void`
にするのが標準的な作法であり、そうすると都合が良い理由もありますが、それはそれとして他の型にしてなにかまずいことが起きるかというと、まあ別に動く」というのが現在の状況です。


CC BY-SA 4.0
2023-10-11T12:08:25.077
96475
2023-10-11T12:08:25.077
60080
96467
answer