【Ruby】RubyKaigi2023で興味を持った技術【RBS】

## はじめに
**RubyKaigi2023**に先日、オンラインで一部参加させて頂きました。

正直言って自分自身の英語力の弱さと相俟って理解出来てない部分も、多数あったかなと思います。

今回はRubyKaigiで紹介されたスライドを紹介しつつ、初めて聞く単語も多かったので気になったもの新しく調べた内容と共にまとめていきます！

## UTF-8 is comming to mruby/c(DAY1)
mruby/cはASCII(バイナリ)のみを使用してきましたが、UTF-8をサポートするようになったとのこと。
mruby/cで利用可能なUTF-8サポートをどのように実装したのかを説明されていました。

### そもそもmruby/cって?
以下しまねソフト研究開発センターより引用
>mruby/cは、Rubyの特徴を引き継ぎつつ、プログラム実行時に必要なメモリ消費量が従来のmruby（福岡で開発された組込み向けの軽量Ruby）より少ないmrubyの実装です。
国立大学法人九州工業大学（田中和明准教授）と共同で研究開発を行っています。

ざっくり言うと、`mruby`という組み込み向けの軽量プログラミング言語をさらにプログラム実行時にメモリ消費量を少なくした軽量タイプです。

Rubyと比較して100分の1の容量で動作するのこと。

### 内容
従来のmruby/cでは文字列に対して`.size`メソッドを使用した際にbyte列として解釈されてしまう問題がありました。
それにより、
```ruby
"💎".size # → 1
```
として出力して欲しいところを、実際は
```ruby
"💎".size # → 4
```

として出力されてしまいました。
他にも`index`,`slice`,`inspect`,`old`などにも問題があるのことでした。

また、💎の絵文字がなぜ4として上記のようになるかというかは下に添付するスライドの44ページ目に説明されております。



`プレゼン資料と詳細について `

https://rubykaigi.org/2023/presentations/ima1zumi.html 

## Let's write RBS!(DAY3)
RBSを使用してコーディングについて、デモンストレーションで解説されていました
特にバージョン3.1の新機能である`subtract`と`parse`について必要な理由と、使用方法について
細かく解説されていました。

## そもそもRBSって?
**RBS**とはRuby3.0で導入されたコードに型を提供する仕組みのことです！
これによって`Go`や`Java`のように静的な型付けが出来るようになりました。

これによりコンパイル時にコードの型エラーを検出することができるため、コードの信頼性と保守性を向上させるのにも役立ちます。

### 実際に書いてみよう
今回は**RBS**とセットで使用されることの多い、**Steep**と**TypeProf**を使って書いていきます！
下記の手順で作業を行なっていきます！

1.クラスが定義されているコードを用意
2.1のコードを**TypePropf**でテンプレートを作成する
3.**Steep**を使用して型エラーを検出する

というわけで上記を検証するために以下のコマンドを叩いておいてください！
```terminal
$ gem install typeprof steep
```

#### 1.クラスが定義されているコードを用意
今回は下記の長方形のクラスファイルを用意します
```ruby:lib/reactangle.rb
class Rectangle
  attr_reader :width, :height

  def initialize(width:, height:)
    @width = width
    @height = height
  end
  
  def area 
    height * width
  end
end
```

#### 2.1のコードを**TypePropf**で実行する
次に**TypeProf**を使用して、型注釈用の`rbs`ファイルを生成します。

```terminal
$ typeprof lib/reactangle.rb -o sig/reactangle.rbs
```
上記のコマンド実行により下記のファイルが作成されます。

```ruby:sig/user.rbs
# Classes
class Rectangle
  attr_reader width: untyped
  attr_reader height: untyped
  def initialize: (width: untyped, height: untyped) -> void
  def area: -> untyped
end

```

今回は元ファイルに型定義されいないので、`untyped`、`void`から型を変えてあげます

```ruby:sig/user.rbs
# Classes
class Rectangle
  attr_reader width: String
  attr_reader height: Integer
  def initialize: (width: Integer, height: Integer) -> void
  def area: -> Integer
end

```

今回はあえて型エラーを検出するためにあえて`width:String`と定義しておきます
これで型を確認するための**RBS**ファイルは完成です!!

#### 3.**Steep**を使用して型エラーを検出する
gemは最初にinstallしていると思うので、
```terminal
$ steep init
```
を叩くと`Steepfile`が生成されます。

生成されたファイルを下記のようにに書き換えます!

```ruby:Steepfile
target :lib do
  check "lib"
  signature "sig"
end
```
それでは`Steep`を使用してみましょう
```terminal
$ steep check
```
を叩くと以下のエラーが出力されるかなと思います
```terminal
lib/reactangle.rb:5:4: [error] Cannot assign a value of type `::Integer` to a variable of type `::String`
...........
lib/reactangle.rb:10:4: [error] Cannot find compatible overloading of method `*` of type `::Integer`
│ Method types:
```
1つ目のエラーは`Integer`を`String`に割り当てられない、`*`と互換性のある`Integer`が見つからないよ〜といったものです

`width:Integer`として正しい型に修正してみてください。
もう1度 `steep check`してください
すると

```terminal
$ steep check
................................................................................

No type error detected. 🫖
```
と出力されエラーがない言葉わかります！

### 内容
前置きが長くなりました。
今回のプレゼンでは`rbs subtract`と`rbs parse`の説明がされていました。
`rbs subtract`は複数ファイルでRBS定義が重複している場合は片方を削除してくれる機能
```terminal
$ rbs substract a.rbs b.rbs # a.rbsからb.rbsの重複したものを差し引いて出力
$ rbs substract --write a.rbs b.rbs # a.rbsからb.rbsの重複したものをa.rbsに上書きする
```
のように実コマンドと実コードを元にデモンストレーションが行われていました。

`rbs parse`はファイルをパースしてSyntax Errorがをみつけてくれるものとして説明されておりました。

詳しく内容を知りたい方は以下を閲覧してください！

`プレゼン資料と詳細について `

https://rubykaigi.org/2023/presentations/p_ck_.html


## 最後に
一部ではありますが、オンラインでRubyKaigi2023に参加できて良かったです。
特に`RBS`についてはとても気になる内容でした。
Rubyにおいても**型がある**のが**マジョリティ**になってるかもと思うと面白いですよね。
今回は`あまり分からない技術`を`慣れない英語でリスニング`したことによって当日すんなり頭に入ってこなかったのかなと思います😵‍💫

最低限自分が気になる講演に関しては予習してから臨もうかなと
~~あ！ここ進研ゼミでやったところだ！くらいの感覚にはしたい~~

来年は今年の現地組くらいの技術力をつけ参加したいです💪

## 参考記事
[Rubykaigi2023](https://rubykaigi.org/2023/) 
[mruby／c](https://www.s-itoc.jp/support/technical-support/mrubyc/#:~:text=mruby%2Fc%E3%81%AF%E3%80%81Ruby%E3%81%AE,%E9%96%8B%E7%99%BA%E3%82%92%E8%A1%8C%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)
[mruby/cとは？mrubyとの違いや開発環境の構築の仕方も解説](https://www.fenet.jp/infla/column/technology/127-2/)
[Rubyで型チェック！動かして理解するRBS入門 〜サンプルコードでわかる！Ruby 3.0の主な新機能と変更点 Part 1〜](https://qiita.com/jnchito/items/bf8c6c2e1dd6cff05f4e)
[Rubyの型を宣言するRBSについて調べてみた。](https://note.com/fukurou_dev/n/n5bc20a87bf01)