Ruby
オブジェクト指向スクリプト言語 Ruby
- Web page: https://www.ruby-lang.org/
- リファレンスマニュアル(Ruby 最新安定版): https://docs.ruby-lang.org/ja/latest/doc/index.html
Topics
【小ネタ】Hash#mergeはキーワード引数でも動作する
RubyのHash#mergeのマニュアルでは、 その引数はハッシュとしか書かれていません。 例えば、以下のような形です。
irb(main):001> {f1: 1, f2: 2}.merge({b3: 3})
=> {:f1=>1, :f2=>2, :b3=>3}
では、キーワード引数を渡すとどうなるのかと言うと、以下のように動きはしますよ、という小ネタです。
irb(main):002> {f1: 1, f2: 2}.merge(b3: 3)
=> {:f1=>1, :f2=>2, :b3=>3}
Rubyの言語仕様上OKなのかは不明ですので、自分から積極的に使うというよりは、 他人のコードを読むときに役立つかもしれない小ネタ知識でした。
RubyのArrayやHashのリテラルをdeep freezeするshareable_constant_valueマジックコメント
概要
Rubyでは、以下のようにshareable_constant_value: literalというマジックコメントを記入することで、
以下の例のように、定数に代入したArrayやHashのリテラルを深く(deeply)freezeすることが出来ます。
# shareable_constant_value: literal
X = [{foo: []}]
X.frozen? # => true
X[0].frozen? # => true
X[0][:foo].frozen? # => true
少し詳しい話
shareable_constant_valueマジックコメントはRuby 3.0で導入されました。
注意点
このマジックコメントのliteralモードでfreezeされるのは定数が対象であるため、 以下のように、代入先が変数である場合にはfreezeされません。
# shareable_constant_value: literal
z = []
z.frozen? # => false
また、このマジックコメントのliteralモードを指定したファイル内では、以下のように、 「freezeされていないオブジェクト」や「freezeされていないものを含むオブジェクト」を定数に代入しようとするとエラーが発生します。
# shareable_constant_value: literal
Y = [{}, Object.new] # => エラー発生
裏を返せば、以下のように、freezeすればエラーが回避できます。 また、freezeする定数とfreezeしない定数でファイルを分けるという自然なアプローチでもエラーを回避できます。
# shareable_constant_value: literal
Y = [{}, Object.new.freeze]
参考文献
Emailアドレスとして適切かどうかのチェックに使えるURI::MailTo::EMAIL_REGEXP
rubyの標準添付ライブラリであるuriに存在しているURI::MailTo::EMAIL_REGEXPは、
ある文字列が規格上Emailアドレスとして適切かどうかのチェックに以下のように利用できます。
irb(main):001> require 'uri'
=> true
irb(main):002> URI::MailTo::EMAIL_REGEXP
=> /\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
irb(main):003> URI::MailTo::EMAIL_REGEXP.match?('[email protected]')
=> true
irb(main):004> URI::MailTo::EMAIL_REGEXP.match?('[email protected]')
=> false
irb(main):005> URI::MailTo::EMAIL_REGEXP.match?('[email protected]')
=> false
Railsガイドでも、 このEMAIL_REGEXPを用いてemailのバリデーションを行う方法を以下のように紹介しています。
validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
URI::MailTo::EMAIL_REGEXPを使うメリット
TechRachoの記事によると、URI::MailTo::EMAIL_REGEXPの正規表現はHTML規格書から持ってきているため、
URI::MailTo::EMAIL_REGEXPを使ったバリデーションはブラウザがinput type="email"で行うバリデーションと一致するというメリットがあります。
余談
URI::MailTo::EMAIL_REGEXPは、
Rubyリファレンスマニュアルにも
Ruby標準ライブラリリファレンスにも、実は記載されていません。
ですので、URI::MailTo::EMAIL_REGEXPを利用するのは少々裏技的な側面があるのかもしれません。
ただ、上述の通り、Railsガイドや記事で取り上げられるぐらいに認知されていますので、利用しても大丈夫なのではないかと思います。
Ruby 4.0では、rdoc gemについて最新バージョンなどを追加インストールすると、gemコマンドの実行で大量のwarningが表示される状態に陥いります。
なお、開発サイドもこの状態を把握しているようですので、個人的には解決されるまで様子を見ようと思っています。
Ruby 4.0の場合
Rubyの4.0系列では、bundled gemの1つとして、rdocが標準添付されています。 ここにrdocの最新バージョンをインストールするようなシチュエーションで、rdocを追加インストールするとwarningが出るようになります。
この現象は、dockerを使うと、以下のように簡単に再現できます。
ruby:4.0.3において、始めはgem -vコマンドの実行でwarningは出ませんが、 rdocをインストールすると、同じgem -vコマンドでwarningが出ていることが確認できます。Ruby 3.4の場合
Rubyの3.4系列では、default gemの1つとして、rdocが標準添付されています。 ここにrdocを追加インストールしてもwarningが出るようにはなりません。
以下はdockerを使ってこのことを確認した様子です。