RubyKaigi 2024 に参加しました

はじめに

5/16(水)~5/18(金) にRubyKaigi 2024 が開催されました。会場は沖縄県那覇市でした。

rubykaigi.org

今年も所属している「永和システムマネジメント」の支援でRubyKaigiに参加できたので記録としてレポートを残します。オフライン参加は3回目です。

今回も前日入りしました。那覇空港の手荷物受け取り所にRubyKaigiの広告があって見逃さず撮ることができました。

セッション

会場の入り口

@tompng さんのキーノートから始まりました。ひとりTRICKの作品には興奮しました。これが自分にできたら楽しいだろうなと思いました。来年にTRICKが開催されるので、自分もチャレンジしてみたいなと思うような内容でした。

@yui-knk さんのパーサの発表では、目指すパーサのマップが出てきて、この部分はこの方が実装してくれているなどチームで分担して目指すパーサができていることを感じました。 前回のRubyKaigiではわからないことが多かったですが、あらかじめ予習をしていたためパーサの大枠の話で迷子にならずに済みました。

@tagomoris さんのNamespaceの発表では、同じクラスだけど異なるメソッドを定義できるものと理解しました。自分が具体的に使う場面があるかわからなかったですが、将来にRubyに入ると目玉の機能になると思いました。

@ima1zumi さんのRelineの発表では、IRB の入力や表示を担っている Reline には機能が足りていないので追加していくという話でした。.inputrc でキーバインドをカスタマイズできることがわかったので、自分も .inputrc で IRB 使いやすくしてみたいなと思いました。発表のあった夜に、前から自分がやりたかったIRBの履歴検索のカスタマイズが .inputrc ではできなさそうだったので、.irbrc をいじってみました。*1

@soutaro さんのRBSの発表では、rbs ファイルに型定義を書くのではなくコード中のコメントで型定義を書くことが提案されていました。 rbs ファイルが不要になると rb ファイルと rbs ファイルを行き来する必要がなくなるのはよいと思いました。一方、コードの行数が長くなったり本来のコメントが埋もれてみづらくなる気もして一長一短だなと感じました。

@koic さんのRuboCopの発表では、前半はLSPで開発体験をよくした話、後半は将来的にPrismを使ってエラートレランスな構文解析を使う話がありました。 前半であった過度にLSPでオートコレクトされる話で、RSpec の fit が it に直されてしまうのは自分がお仕事で起きた問題でした。Kaigi 後に RuboCop RSpecAutoCorrect: contextual をデフォルトにする提案の issue を @ydah さんが立てられていました。*2

@S.H. さんのLTの発表では、初めてRubyのパーサにコントリビュートする話でした。 @S.H. さんのできることをやってみたということで、parse.y をルールを使って書き換えることで簡略化する Pull Request を作ったそうです。OSS の取り組み方として参考になりました。まず『Rubyのしくみ』で勉強をしたというがありましたが、自分も事前に読んでおくことで RubyKaigi の発表が理解しやすくなったと感じたので、いい本だなと思いました。

@junk0612 さんのIELRパーサジェネレータを実装した話は、パースアルゴリズムが色々出てきて関係性を整理するのが難しそうに思いました。LexerとParserを分けないScannerless Parserがこれまでと異なる種類のパースアルゴリズムということがわかりました。論文を見ながらRubyで実装したということで、論文を読む力が必要で大変だなと思いました。

後日セッションの感想を書いているとどんな話だったけというのが多かったので、すぐにメモを取った方がよかったなと反省しました。

イベント

ナイトクルーズ

Day0に所属している「永和システムマネジメント」主催のイベントでナイトクルーズがありました。2019の福岡のRubyKaigiに続いて2回目のナイトクルーズでした。定員の130名がすぐに募集が埋まっていてとてもありがたかったです。 自分は乗船前の受付でQRコードを読み取る係をしていました。

船では3階のデッキに出てゆったりと風景を楽しめると思っていましたが、あいにく大雨になってしまい景色を楽しむことはできませんでした。残念...。

参加された方はみなさん楽しまれていたようで嬉しかったです。

オフィシャルパーティー

Day1の夜はオフィシャルパーティーでは海辺にある施設の野外でBBQでした。大人になって久しぶりのBBQでしたし、開放的な場所で楽しかったです。 海の景色もとてもよかったです。一緒のテーブルになった初めての方とお話もできてよかったです。

アフターパーティ

Day3の夜は mov さん主催のアフターパーティに参加しました。国際のれん街という飲み屋が入った施設を貸し切って開催されました。いろんな店舗の料理が食べられるのがよかったです。ドリンクをチケットで交換できるのもいいアイデアだなと思いました。

LTを発表された @S.H. さんと一緒の席で飲んでいました。

スポンサーブース巡り

今年もスポンサーブースを巡って、スタンプラリーをしました。

STORESさんのRubyエラークイズは面白かったです。開発していてよく見るエラーメッセージは簡単でしたが、あまり使ったことがないメソッドで発生するエラーはまったくわからなかったです。

mybest さんのブースで回したガチャ*3で1等が出て高級ドライヤーをいただきました。スポンサーブースのガチャやくじで大当たりを当てたことがなかったので、まさか当たるなんて思ってなかったのでとても嬉しかったです。

那覇を楽しむ

Rubyist が行っていると X でよく流れていたステーキ屋に行かないと後悔すると思ったので、そこでステーキを食べました。ジューシーでとてもおいしかったです。

ステーキにはハマって3店舗に行きました。あと昼食に沖縄そばのお店にも1回行きました。 国際通りにも行ってお土産を買ったりしました。お土産屋がいくつもありいろいろ見ながら選べたのでよかったです。

おわりに

来年の開催地は松山でした。来年もぜひ参加したいですね。参加してみて刺激を受けたので来年までに、コミュニティに参加して Rubyist の知り合いを増やしたり、OSS 活動をしたいなと思いました。

IRB の補完機能の色を設定してみた

この記事は、所属している永和システムマネジメントのアドベントカレンダー ESM Advent Calendar 2023 の 2 日目の記事です。

はじめに

11月にリリースされた Reline の v0.4.0 から Reline::Face というクラスが登場しました。

github.com

これによって、IRB のメソッド補完ダイアログの色を変えることができるようになりました。

今回はその色を変える設定をしてみたことについて書いていきます。

設定方法

設定方法は Reline::Face のドキュメントに書かれてます。

まず Reline の v4.0.0 以上がインストールされていなければ Reline の最新版をインストールしましょう。

gem  install reline

次に .irbrc へ設定を書きます。 Reline::Face.config(:completion_dialog) にブロックを渡して設定します。

サンプルコードは以下です。

# .irbrc

Reline::Face.config(:completion_dialog) do |conf|
  conf.define :default, foreground: :white, background: :blue
  #                                                     ^^^^^ `:cyan` by default
  conf.define :enhanced, foreground: :white, background: :magenta
  conf.define :scrollbar, foreground: :white, background: :blue
end

conf.define の引数に、色を変えたい対象、文字の色( :foreground )、背景の色( :background ) を渡すことができます。

色を変えたい対象として、補完候補の表示部分(:default)、選択された補完候補の部分(:enhanced)、補完候補のスクロールバーの部分(:scrollbar) の3箇所の色を変えることができるようです。

指定する色は、ドキュメントの表に書いてある :blue などの用意されたラベルの色を使う他にも、"#FF1020" のように16進カラーコードで細かく色を表現することもできます。

他にも :style オプションを渡して :bold などを指定することで、文字を太字にするなどの装飾をすることもできます。

実際に設定した内容

自分以下のように設定しました。

# .irbrc

Reline::Face.config(:completion_dialog) do |conf|
  conf.define :default, foreground: :white, background: '#2C2B2B'
  conf.define :enhanced, foreground: '#FFFFFF', background: '#005bbb'
  conf.define :scrollbar, foreground: :gray, background: '#2C2B2B'
end

ターミナルの黒い画面に目立ち過ぎず馴染むような色にしました。

補完候補の表示部分は、文字の色を white にして背景色を blackより少し明るい黒色にしました。選択された補完候補の部分は、白色にして背景色を青色にしました。スクロールバーの部分は、バーの色を gray にしてバーの背景色を black より少し明るい黒色にしました。

どのように変わったか

設定前

自分はターミナルアプリに iTerm2 を使っており、Monokai Soda というテーマを設定しています。

そのテーマと補完のデフォルトの色との相性が悪いようで、補完候補の部分の文字色が白色で背景色が水色になっており、目を凝らさないと見えないくらい見づらい状態でした。

設定前

設定後

設定後はくっきり見えるようになり使いやすくなりました  🎉

設定後

おまけ:バージョンによっては補完機能を無効にしたい

色を設定する以前は、補完候補が見づらく実用的でなかったため補完機能を無効にしていました。

# .irbrc

IRB.conf[:USE_AUTOCOMPLETE] = false

色を設定したことで補完機能を無効にする記述は消すことができると思ったのですが、 Reline::Face が利用できるのは Reline の v0.4.0 からなので、Bundler の Gemfile.lock などで v0.4.0 より前のバージョンを固定して使われると Reline::Face が利用できません。

そのため Reline が v0.4.0 以降であれば色の設定をするようにして、前であれば補完機能を無効にする条件分岐を入れてみました。

# .irbrc

if Gem::Version.new(Reline::VERSION) >= Gem::Version.new('0.4.0')
  Reline::Face.config(:completion_dialog) do |conf|
    conf.define :default, foreground: :white, background: '#2C2B2B'
    conf.define :enhanced, foreground: '#FFFFFF', background: '#005bbb'
    conf.define :scrollbar, foreground: :gray, background: '#2C2B2B'
  end
else
  IRB.conf[:USE_AUTOCOMPLETE] = false
end

さいごに

IRB の補完機能をどんどん使っていきたいです。ますます便利になっていく IRB に期待です。

Kaigi on Rails 2023 に参加した

先週 Kaigi on Rails 2023 がありました。

kaigionrails.org

登壇・参加ブログをいろんな方が書いていたので、自分も簡単に書いてみました。

スポンサー

所属する永和システムマネジメントではスポンサーブースで、Rubyメソッドキーホルダーを配布しました。名札に付けていただいていたり楽しんでもらえてよかったです。もらって下さった方ありがとうございました。

blog.agile.esm.co.jp

セッション

発表資料のまとめはこちら。

qiita.com

発表を聴講した中で、特に普段から気になってた内容に近い発表をピックアップします。

初めてのパフォーマンス改善

初めてのパフォーマンス改善 - Speaker Deck

ふーがさんの発表。SQLでパフォーマンス改善をするときに、どのような手順で進めたらよいかというのがわかりやすかった。また「コードにしたものとコードにしなかったことがプログラミング」について、PRにはコード以外の調査についての情報も大事なので、しっかり載せるのはやっていきたいと思った。自分もちょうどその時ふーがさんと同じチームだったので、New Relicの使い方を教えていだいたりした。

Simplicity on Rails -- RDB, REST and Ruby

Simplicity on Rails -- RDB, REST and Ruby - Speaker Deck

moroさんの発表。イベントエンティティを見つけてDB設計をするのがシンプルにするために大事。イベントエンティティは"登録すること"といった行為を指し示す。イベントエンティティを見つけると行為が起きた時間をもたせるなどができる。まだDB設計に慣れていないので、イベントエンティティを見つけられるようになりたいと思った。

ペアプロしようぜ 〜3人で登壇!? 楽しくて速いペアプロ/モブプロ開発〜

ペアプロしようぜ 〜3人で登壇!? 楽しくて速いペアプロ/モブプロ開発〜/pair-mob-programming-kaigi-on-rails-2023 - Speaker Deck

トミーさん、masuyama13さん、あんすとさんの発表。発表に勢いがあって一番聞いていて楽しめた発表だった。前半のなぜペアプロをするのかについての根拠のために、データをたくさん載せていたのが大事なことだなと思った。後半は実際にペアプロをライブコーディングしていただいてライブ感がよかった。指示するときにペンツールをよく使われていたので自分も使っていこうと思った。一方通行にならないように、ドライバーとナビゲーターの役割を区別するのも大事だとわかった。この発表を聞いてベテランと新人でペアプロするときにどのようなところに気をつけるとよいかが新たに気になった。

その他

懇親会では、ブログをよく見させていただいていたインターネットでアイコンだけしか知らなかった方々に実際にお会いして、お話もできてどういう方なのかを知れてよかったです。

Kaigi on Rails中に使っていたKaigi on Rails アプリ *1が、ブックマークした発表の時間になったら通知してくれるので便利でした。

運営の皆様ありがとうございました。

TablePlus で日本語の文字列の値が question mark (?) で表示された場合の対処法

実行環境

TablePlus: Version 5.3.1

困りごと

TablePlus を初めて使ってみたとき、Oracle のデータベースと connection してテーブルのデータを見てみました。

すると、ひらがなや漢字が値として入っているカラムの値が、 question mark (?) で表示されてしまいました。

解決方法

そんなときは、

Connection -> View Using Encoding

が最初は Default になっているので、JAPANESE_JAPAN.UTF8 に変更してください。

TablePlus のアプリを落として再起動すると、正しく日本語が表示されるようになりました!

参考: https://github.com/TablePlus/TablePlus/issues/713#issuecomment-522823057

VSCode を開いた時、「"java"コマンドラインツールを使用するには、JDKをインストールする必要があります。」が表示される問題

はじめに

あるときから、VSCodeを開いた時に、

「"java"コマンドラインツールを使用するには、JDKをインストールする必要があります。」

というポップアップがでるようになりました。

普段の開発で Java は使っていないので、とくに Java をインストールしたくありませんでした。そのため、毎回このポップアップがでるのが煩わしかったです。

インストールしている何かしらの拡張機能Java を利用しているのが原因と予想しました。拡張機能を一つずつ無効にしていったところ、原因が判明しました。

原因

「PlantUML」という拡張機能が原因でした。

marketplace.visualstudio.com

Java : Platform for PlantUML running.

たしかに PlantUML を実行させるために Java が必要と書いていますね。

解決方法

PlantUML は利用していなかったので、PlantUML を無効にするかアンインストールすることでポップアップが出なくなりました!


この記事がどなたかのお役に立てられれば幸いです。

JSON型カラムをActiveRecord::Storeで使いやすくしてみる

今回はRails アプリケーションの開発でJSON型のカラムを扱った際に ActiveRecord::Store を使うと便利だったのでそのことについて共有します。

実行環境

以下の環境で試しました。 - Ruby 2.7.1 - Rails 6.0.3.2 - Postgres

JSON型について

PostgresqlではJSONデータ型をサポートしています。 https://www.postgresql.jp/document/12/html/datatype-json.html

Railsではcreate_tablejson型のカラムを作ることができます。同様にjsonb型のカラムも作ることができます。 https://railsguides.jp/active_record_postgresql.html#json%E3%81%A8jsonb

例題をつかって試してみる

例として、profile という json 型カラムを持つ users テーブルを定義することにします。

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.json :profile

      t.timestamps
    end
  end
end

以下のモデルも定義します。ひとまず何もない空のクラスにします。

class User < ApplicationRecord
end

この状態で適当なデータを作って、json型カラムの中の値を参照してみます。

user = create(profile: { name: 'Ken', age: 20 })

user.profile
#=> {"name"=>"Ken", "age"=>20}

user.profile['name']
#=> "Ken"

user.name
#=> NoMethodError (undefined method `name' for #<User:0x00007f9f8d20f510>)

最後の行で試した user.name ですが、 nameというカラムは無いため NoMethodError になってしまいます。

store_accessor

そこで、 store_accessor を使ってみます。

api.rubyonrails.org

以下のように User クラスの中に書きます。第一引数にはjson型のカラム名(今回は :profile)、第二引数以降にはkey(今回は :name, :age)を書きます。

class User < ApplicationRecord
  store_accessor :profile, :name, :age
end

すると nameage のGetter・Setterメソッドが追加され、通常のカラムと同様に扱えるようになります。

user.reload.profile
#=> {"name"=>"Ken", "age"=>20}
user.name
#=> "Ken"
user.age
#=> 20

user.age = 30
user.age
#=> 30
user.changed?
#=> true

user.save
#=> User Update
user.reload.profile
#=> {"name"=>"Ken", "age"=>30}

また、設定した属性の一覧は Model.stored_attributesで確認できます。

User.stored_attributes[:profile]
#=> [:name, :age]

バリデーションも行える

通常のカラム同様に使えるようになるので、もちろん バリデーション も設定することができるようになります。

class User < ApplicationRecord
  store_accessor :profile, :name, :age
  
  validates :name, presence: true
end
user.name = ""
user.save!
#=> ActiveRecord::RecordInvalid (Validation failed: Name can't be blank)

accessors を overwrite

Getter・Setter メソッドはsuperを使うことで overwrite できます。 例えばnameが大文字で返すかつ、age=で代入するとIntegerに変換されるようにしてみました。

class User < ApplicationRecord
  store_accessor :profile, :name, :age
  
  validates :name, presence: true
  
  def name
    super.downcase
  end
  
  def age=(number)
    super(number.to_i)
  end
end
user.profile
#=> {"name"=>"Ken", "age"=>20}
user.name
#=> "KEN"

user.age = "30"
user.profile
#=> {"name"=>"Ken", "age"=>30}

参考URL

https://api.rubyonrails.org/classes/ActiveRecord/Store.html

describeとRSpec.describeはどちらの書き方が良いのか

この記事は「ESM Advent Calendar 2021」の3日目の記事です。

adventar.org

はじめに

Railsアプリケーションをの開発でRSpecを使ってテストを書くことが多いです。私はRSpecを書くときに、トップレベルの階層の describe をdescribe ではなく RSpec.describe でいつも書いています。

トップレベルに describe を書くパターン。

descirbe User, type: :model do
  descirbe "foo" do
    # ...
  end
end

トップレベルに RSpec.describe を書くパターン。

RSpec.descirbe User, type: :model do
  descirbe "foo" do
    # ...
  end
end

どちらの書き方でも動作します。

ちなみに、rspec/rspec-core のREADMEでは RSpec.describe の書き方で統一されています。

github.com

どちらの書き方が推奨されているか気になったので、調べてみることにしました。

調べたこと

stack overflowでまさにこれの質問を見つけました。

stackoverflow.com

回答によるとRSpec バージョン3からは describe の書き方制限するオプションが新たに加えられたそうです。

relishapp.com

後方互換性を維持するためconfig.expose_dsl_globally がデフォルトで true になっており、 describeRSpec.describe も書くことができるようにはなっています。

ただし、expose_dsl_globally = false を設定すると describe だと "undefined method 'describe'" にすることができます。

この辺りのバーション3系のアップデートを日本語でまとめている記事もありました。

nilp.hatenablog.com

また generator が作るspecファイルも RSpec.describe の書き方に書き換えられている。

github.com

まとめ

調査から分かったこと

  • バージョン3から describe の書き方を禁止するオプションが追加された。
  • describe はmainをモンキーパッチしているためあまりよくない
  • RSpec側でもREADMEなどが RSpec.describe に書き換えられて、主流になっている模様

追記

expose_dsl_globally = false とする代わりに、

RSpec.configure { |c| c.disable_monkey_patching! }

とすることでも describe の書き方を禁止することができます。

expose_dsl_globally = false よりも強力にモンキーパッチを禁止することができるため、私もあまり使ったことがなかった shouldstub といったメソッドも禁止にできるようです。

relishapp.com