週刊Railsウォッチ(20180525)特集: RubyKaigi 2018いよいよ来週、Rails vs Hanami対決、命名にはシソーラス使おうほか

こんにちは、hachi8833です。最近Macの+Ctrl+spaceで顔文字を出す技を教わりました😊。問題は、漢字と違って顔文字には定まった読み仮名がないことです(´・ω・`)。

ご家族みんなで楽しめるウォッチ、いってみましょう。

各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ

なお来週の週刊RailsウォッチはRubyKaigi参加のためお休みです🙇。

特集: RubyKaigi 2018情報

RubyKaigi 2018もいよいよ来週ですね。皆さま覚悟は完了ですか?


http://rubykaigi.org/2018より

事前情報


るびまより


つっつきボイス: 「お、今年もるびまが特集組んでますね」「記事募集中とのことなので、せっかくだからTechRachoからも出そうか?」「いいですね!😀」「今回分のRailsウォッチでエントリ応募するとか」「(受け付けてもらえるかな…ドキドキ)」

追記: 掲載いただきました🙇。


スピーチの内容をざっくり知りたい方には、RejectKaigi 2018の「RubyKaigi 2018タイムテーブル徹底解説」レポートが便利です。

アンチハラスメントポリシーとは

改めて読み直してみました。

RubyKaigi は、誰もがハラスメントを受けずに参加できるカンファレンスを目指しています。いかなる形であれハラスメントは許容できません。このルールを破る人は誰であろうと、オーガナイザーの裁量で制裁措置を加えたり、カンファレンスから出入禁止とすることもありえます。
同ポリシーより抜粋


つっつきボイス: 「この話も何度かしたと思うんですが、このアンチハラスメントポリシーを見るたびにRubyコミュニティって偉いなって思うんですよ」「私もです」「カンファレンスが公式にこうしたポリシーを表明するのは、他のカンファレンスもぜひ参考にするといいと思いますね」「レースクイーンやキャンペーンガールみたいな演出もありませんしね」「😅そういうのよりは、カンファレンスの場を不快にしないように皆んなで気をつけようねっていうメッセージ: この雰囲気が実は大事だし、貴重」「このポリシーが定まっていて、雰囲気が確立していることで、来場する人が安心できるし、仮に有名OSSのコミッターや偉い人がこれに反する言動をしたときに諌めることもできるし」「今のところ見たことありません」

「この雰囲気づくりには、Matz自身の人柄の影響も結構あるんじゃないかなと思う」「あー、それはこれまでカンファレンスに参加していて感じました: Matzは特定のコミッターとだけ固まって行動したりしないですよね」「それもあるし、あまり極端な価値観を持ち込まないようにしているところとか」「Matz自身があまり群れたがらない方なのかなとも思ったりしましたが」「いや、意識的にやってると思いますよ: 排他的にならないことについて」

生まれてこの方、主流派気分というものを一度たりとも味わったことのない私には、本当にうれしい配慮です🤓。皆さんも会場でいろんな方に話しかけてみましょう🐹。海外から来た方は特に会話に飢えてますので、「May I join you?」でいってみましょう↓。

ガイジン向けRubyKaigiガイド(翻訳)

米国から見た日本のRuby事情(翻訳)

パーティ情報

皆さまパーティのブッキングは完了でしょうか?
RubyKaraokeだけまだ募集が始まってないようですが、たぶんエントリ開始とともに激戦が始まる予感です。

以下のツイートは上から目についたものを貼りました。網羅できなかった方ごめんなさい🙇。


つっつきボイス: 「そういや今回はプレパーティ以外あまりエントリしなかったナ: 行きたい店もあるし🍺🍶」「私アクセス集中でプレパーティ押し出されちゃいました(´・ω・`)」「マジでw」「まー仙台だったら正直どこででも飲めるけどねっ😎」「上のツイートには『会場の周りはなんもない』ってありますけど」「あそこは公園だしwそりゃそうだ: でもタクシーでもせいぜいワンメーター、その気になれば徒歩でも少し頑張れば飲み屋街に楽勝でたどり着けますよ」

国分町あたりまで来れば店いくらでもあるので大丈夫↓: 自分の宿もこの近く」「おー❤️」「自分は味・雰囲気優先なので、朝までやってる店は基本行きませんけどね😝」「仙台といえば牛タン!🐮」「牛タン攻略は昼か夕方の早い時間に行くのがおすすめかな」

その他情報


つっつきボイス: 「Photo Sponsorかー: そうそう、RubyKaigiのスポンサー受け付けフォームは、通常のスポンサー枠の他に、『これやらせてください!』って独自のスポンサー活動を申請することもできるんですよ」「おー、知りませんでした!」
「万葉さんの託児サービススポンサーもおなじみですね: 子連れでも来場できるのがうれしいです👼🏽👶」

TechRachoとBPS株式会社よりお知らせ

最後にTechRachoとBPS株式会社からのお知らせです。


Sponsors - RubyKaigi 2018より

Rails: 今週の改修

公式の更新情報がなかったので、以下はRails 5.2リリースノートの中から、これまで取り上げていなかったものを見繕いましたので、すべてRails 5.2が対象です。

(5.2) ActiveSupportのModule#reachable?を非推奨化

非推奨化の理由はこのPRには書かれていませんでした。

3.5 到達可能
名前を持つモジュールは、対応する定数に保存されている場合に到達可能 (reachable) となります。これは、定数を経由してモジュールオブジェクトに到達できるという意味です。
これは通常の動作です。”M”というモジュールがあるとすると、Mという定数が存在し、そこにモジュールが保持されます。
しかし、定数とモジュールが実質上切り離されると、そのモジュールオブジェクトは到着不能 (unreachable) になります。
Railsガイド Active Support コア拡張機能より

# 同ガイドより
module M
end

orphan = Object.send(:remove_const, :M)

# このモジュールは孤立しているが、まだ無名ではない
orphan.name # => "M"

# 定数Mは既に存在してないので、定数Mを経由して到達できない
orphan.reachable? # => false

# "M"という名前のモジュールを再度定義する
module M
end

# 定数Mが再度存在し、モジュールオブジェクト"M"を保持しているが
# 元と異なる新しいインスタンスである
orphan.reachable? # => false

つっつきボイス: 「reachable?あー、そういうことか」「Railsガイドなんで訳語の『到達可能』は私がやったやつですが、英ママの方がよかったかな…」「非推奨化の理由ほんとに書いてないや」

普段はカンニングしないようにしてるのですが、y_yagiさんのブログを参照しました↓。

参考: rails commit log流し読み(2017/09/21) - なるようになるブログ

Active Supportの修正です。Module#reachable?メソッドをdeprecateにしています。rails内部でもう使用してない為deprecateにしたとの事です。
同ブログより

(5.2) config/database.ymlにすべての環境で読み込まれる共有セクションを追加

# railties/lib/rails/application/configuration.rb#L133
         config = if yaml && yaml.exist?
           require "yaml"
           require "erb"
-          YAML.load(ERB.new(yaml.read).result) || {}
+          loaded_yaml = YAML.load(ERB.new(yaml.read).result) || {}
+          shared = loaded_yaml.delete("shared")
+          if shared
+            loaded_yaml.each do |_k, values|
+              values.reverse_merge!(shared)
+            end
+          end
+          Hash.new(shared).merge(loaded_yaml)
         elsif ENV["DATABASE_URL"]
           # Value from ENV['DATABASE_URL'] is set to default database connection
           # by Active Record.

マージ後にも議論が続いていました。

  • #28095とコンフリクトするのでは?
  • 5.1へのバックポートは止める方がよさそう
  • DHH: YAMLへのパッチという形は好きでない。概念として共有される分にはいいけど、secretsと同様読み出し時に行うべき云々

つっつきボイス: 「あーなるほどね! 確かにこの修正は欲しいヤツ」「というと?」「rails newするとdefaultってセクションができるんで、みんな慣例的にいちいちYAMLにデフォルト設定書くんだけど、そのデフォルト読み込みを書き忘れる人が続出しがちだったんで」「おー😮」

「ただねー、これをサポートするのがいいかどうかというのはあるんですよ: (他でも使う可能性のある)ピュアなYAMLとしては汎用性が下がっちゃうことにはなるんで」「むむ?」「このYAMLをピュアなYAMLとして読み込んだときに挙動が変わっちゃうから」「あ!🤭」

「ちなみにプルリクメッセージ↓に書いてある& <<: *ってYAML標準の記法っす: これを使えばYAML.loadなんかでRailsとは無関係に読み込める」「しかし今回のようにYAMLにsharedという特殊な名前のセクションを追加してやる場合は、Railsがこのコード経由でdatabase.ymlを読み込んだ時だけはその設定が効くんですが、YAML.loadとかで読み込むとデフォルトと異なる動作になる」「😓」「言い換えれば、RailsがYAMLを読み込むときにはそういう特別扱いをする形になるんで、下手をするとbreaking changesになるかも」

I’ve discovered this commit from @dhh to have a shared section for secrets.yml today at @claudiob ‘s talk at RailsConf.
I really like the idea and since all the database.yml that I’m working with have some & <<: * shenanigans, I thought it would be nice to make it available there as well.

「それでshenanigansって言葉が使われてるのか: 『ごまかし』とか『ペテン』みたいな意味があるんだそうで、私も初めて見た単語」「上のDHHの発言↑もまさにそれで、これを入れるとピュアなYAMLではなくなるからでしょう」「ただ、既存のYAML記法は引きつづき使えるので、YAML.loadとかでRails以外からdatabase.ymlを読み込む可能性のあるシステムでは、引きつづき <<: *name を使ったほうが良さそう」「😃」

参考: Rubyリファレンスマニュアル library yaml (Ruby 2.5.0)

「それにしてもこの& <<: *って記法のあたり覚えらんねぇw: 毎回ググってるし」「でしょうね…目に痛い🦔」「でもこれがないとYAMLの表現力がガタ落ちになっちゃうんで」

参考: YAML™ Specification Index
参考: YAML - Wikipedia
参考: yaml を DRY に書く - Qiita

「そっかー、私はYAMLは静的なデータファイル形式的な使い方しかしたことなかったのもあって、そういう動的っぽい仕様を知らなかった😓」「YAMLはこういうことができるから優秀なんですよ🧐: それこそローカライズなんかにはうってつけの機能で、こうやってデフォルトロケール向けの設定を& <<: *で読み込んだうえで個別のロケール設定を読み込んでおけば、該当ロケールがなくてもデフォルトにフォールバックしてくれて、translation missingにならずに済むと」「そうだったのかー!😲YAMLの機能だけでここまで実現できるということか」

参考: Rails国際化 (I18n) API | Rails ガイド — 近々Rails 5.1対応向けに更新します。


railsguides.jpより

(5.2) デフォルトでGemfileと.ruby-versionにRubyバージョンが設定されるようになった

これもマージ後にスレが伸びていて、DHHが「revertをrevertした: 混乱させてすまない」と書き込んでる一幕もありました。

# railties/lib/rails/generators/rails/app/templates/Gemfile
 source 'https://rubygems.org'
 git_source(:github) { |repo| "https://github.com/#{repo}.git" }
+ruby <%= "'#{RUBY_VERSION}'" %>
# railties/lib/rails/generators/rails/app/app_generator.rb#L52
+    def ruby_version
+      template "ruby-version", ".ruby-version"
+    end

つっつきボイス: 「へー、いつの間にこれが?」「私rails newばっかやってるのでこれは見かけてました」「確かにいつ入ってもおかしくない機能ではある」

「そうそう、こういうのって採用面接なんかで相手がリポジトリに上げてきたRailsアプリをチェックするときの第一関門になるんですよ😉: 普段からRailsを触っている人なら必ず.ruby-versionを置くものなんですけど、それ置いてないRailsアプリを取ってくるとたいてい動かない😎」「🤣」「個人開発者で他の人と共同開発をやったことのない人にありがちな初歩的ミス😇」

出かけるときは忘れずに。

(5.2) mini_magickをデフォルトでGemfileに追加(ただしコメントアウト状態で)

# railties/lib/rails/generators/rails/app/templates/Gemfile#L24
+# Use ActiveStorage variant
+# gem 'mini_magick', '~> 4.8'
+

先週のウォッチでお伝えしたように、Rails 6ではImageProcessingやruby-vipsを使う流れになっています。短い命🐞。


つっつきボイス: 「あれあれ?mini_magickは確か先週…?」「↑そういうわけでRails 5.2だけということに」

(5.2) ActionDispatch::TestResponseのレスポンスエイリアスを非推奨化

#30072を修正する。実際のActionDispatch::Responseオブジェクトは#success?#missing?#error?をサポートしていないので、サポートされていると誤解されないようにする。代わりにRack::Responseのレスポンスヘルパーを使うこと。
同プルリクより大意

# actionpack/lib/action_dispatch/testing/test_response.rb#L22
     # Was the response successful?
-    alias_method :success?, :successful?
+    def success?
+      ActiveSupport::Deprecation.warn(<<-MSG.squish)
+       The success? predicate is deprecated and will be removed in Rails 6.0.
+       Please use successful? as provided by Rack::Response::Helpers.
+      MSG
+      successful?
+    end

     # Was the URL not found?
-    alias_method :missing?, :not_found?
+    def missing?
+      ActiveSupport::Deprecation.warn(<<-MSG.squish)
+       The missing? predicate is deprecated and will be removed in Rails 6.0.
+       Please use not_found? as provided by Rack::Response::Helpers.
+      MSG
+      not_found?
+    end

     # Was there a server-side error?
-    alias_method :error?, :server_error?
+    def error?
+      ActiveSupport::Deprecation.warn(<<-MSG.squish)
+       The error? predicate is deprecated and will be removed in Rails 6.0.
+       Please use server_error? as provided by Rack::Response::Helpers.
+      MSG
+      server_error?
+    end

つっつきボイス:ActionDispatchは、泥臭いことをやるときにたまに使う」「コントローラがらみということですね」「たとえばrakeタスクから無理やりコントローラを叩きたい!みたいなときに、ActionDispatchを使うとあたかもコントローラの中から呼んでるかのような振る舞いを得られる」「あー、コントローラのコンテキストで呼べるのか!😲」「そそ、コントロラーのメソッドはそのままじゃ外から呼べないんで、「ActionDispatchから呼ばないとコンテキストが形成されない」

「何年か前に社内勉強会でも同じこと話した覚えがあるんですが、たしかいましたよねそんとき?」「…ちょっとだけ思い出した😓」「ま、使わなきゃ忘れるヤツですし😼」

(5.2) 非推奨化されていたActionController::ParamsParser::ParseErrorを削除

# actionpack/lib/action_dispatch/http/parameters.rb#L126
-
-  module ParamsParser
-    include ActiveSupport::Deprecation::DeprecatedConstantAccessor
-    deprecate_constant "ParseError", "ActionDispatch::Http::Parameters::ParseError"
-  end

Rails 4まではパースエラーについて以下のように対応してたようです。

参考: Rails で JSON のリクエストパラメータがパース出来なかった場合の対応 - Qiita


つっつきボイス: 「何が変わったのかな?と思って」「別の場所でパーサーエラーに対応するようになったとかですかね🤔」

再度y_yagiさんブログより:

Action Packの修正です。ActionDispatch::ParamsParser::ParseErrorクラスがdeprecateになりました。今後はActionDispatch::Http::Parameters::ParseErrorを使用する必要があります。
rails commit log流し読み(2016/10/10) - なるようになるブログより

参考: Deprecated ActionDispatch::ParamsParser::ParamsParser · rails/rails@b3d41ea

ActionDispatch::ParamsParserクラスが削除されてActionDispatch::Http::Parametersに代わったので、エラー定数はこの新しいクラスに置くのがよい
b3d41eaより大意

参考: DevDocs — Ruby on Rails 5.2 / ActionDispatch::Http::Parameters

Rails

Yuguiさんが教える「適切なコメント」


つっつきボイス: 「まー昨今コードにコメントを書かないなんて人がもしいるとすれば、複雑なコードや難しいコードを普段書いていないか周りに迷惑をかけまくってるかどちらかでしょう: ま、たまにいますけど😆」「😆」

「あれはいつだったか、ソースコードに一行たりともコメントが書かれていない凄いのを見たことがありますよ」「Σ(゚◇゚;)マジデッ!?」「コードコメントがないと、他社開発のシステム引き継ぎなんかで調査・把握にかかる工数がバーンと跳ね上がりますから」「そりゃそうですね😵」「publicなメソッドの全部にみっちりコメント書くとまでいかなくても、ちょっとでもロジックが複雑なメソッドには必要なコメントを書いてもらわないと下手すればメンテ不能で作り直しだし、それ以前に触りたくない💩」「コードをクイズにしたらいかんですよね…」

最近のWeb認証

参考: Web Authentication: An API for accessing Public Key Credentials - Level 1 — w3cもすなるgithub.io
参考: パスワードレス認証技術 FIDO | NTTデータ
参考: U2F - FIDO Universal 2nd Factor Authentication | Yubico
参考: Credential Management Level 1 — W3C

今週は心なしかy_yagiさん成分が多めになりました。


つっつきボイス: 「FIDOとかYubiKeyとか、知らない用語が出てきたので」「お、例のjxck.ioさんのブログ: さすがいつも詳しい」「↓動画でもやってますが、こうやってUSBキーを挿して認証できる」「おー、それをブラウザでやれると」「まー最近流行りの仮想通貨周りなんかにはいいんじゃない?」

ByebugとBootsnapを両方使う場合の注意

@hashwin 以下のconfig/boot.rbの設定は動きそう。bootsnapのREADMEのデフォルト推奨設定だけど、compile_cache_iseqfalseにしてある。
同issueより大意

# 同issueより
require 'bootsnap'

env = ENV['RAILS_ENV'] || 'development'

Bootsnap.setup(
  cache_dir: 'tmp/cache',
  development_mode: env == 'development',
  load_path_cache: true,
  autoload_paths_cache: true,
  disable_trace: true,
  compile_cache_iseq: false,
  compile_cache_yaml: true
)

つっつきボイス: 「今はBootsnapがRailsでデフォルトで入るからなー」「まだissueクローズしてませんでした」「iseqはInstructionSequenceのことですよね?」「👍」「Bootsnapは高速化のためのgemだから、おそらくdevelopment環境でキャッシュされるとByebugとかそっちの方で不都合があるんでしょうね」

参考: Rubyリファレンスマニュアル class RubyVM::InstructionSequence

RailsConf 2017のパフォーマンス関連の話題(1)BootsnapやPumaなど(翻訳)

コントローラ対決!Rails vs Hanami

予想外に短くて読みやすい記事です。翻訳依頼かけてみます。

  • Railsのコントローラ
  • Hanamiのコントローラ
  • 相違点
  • どっちがどう良いのか
  • ビュー/テンプレートへの変数の公開

つっつきボイス: 「そういえば今年もHanamiの中の人来るんだっけ?」「来ますね」「自分もまあ、APIというかマイクロサービス寄りのサーバーならRailsのような重たいものでなくてもいいんじゃね?とは思う: それこそSinatraでいいくらいだけど、Sinatraだと結局あとからあれが足りないこれが足りないみたいになりがちだし」


sinatrarb.comより

「Hanamiは高速化も頑張ってるという話も伝え聞くし、不可思議な挙動とかもなさそうだし、マイクロなサービスならHanamiは選択肢として悪くないんじゃないかなとも思うし」「記事の結論でも、Hanamiだとコード量は多めになるだろうとなっていて、先週のウォッチでのTrailbrazerの話をちょっと思い出しちゃいました」「その結論でもCOC(設定より規約: Convention over Configuration)について触れているようにRailsはいろんなものが背後に隠れてるから、そりゃRailsの方がコードは少なくなる😆」「😆」


trailblazer.toより

「そしてTrailblazerとHanamiはおそらく立ち位置が違う: Trailblazerは規約が固めで明示的に制約をかけられる感じで、おそらくJava方面に多い固めのフレームワークに近いから、規約はそれなりにあるはず」「ふむふむ」「逆にHanamiはその結論にも書いてあるように規約が少ないから、自由度が高い分自分で書かなきゃいけないコード量も増えるということでしょうね」「😃」「じっくり取り組める案件があるならHanami使ってみたいな」

Hanamiフレームワークに寄せる私の想い(翻訳)

rails_db: データベースビューア&クエリランナーgem(RubyFlowより)



同リポジトリより

昨年のウォッチ↓でも取り上げたrails_dbがメジャーアップグレードしたそうです。

週刊Railsウォッチ(20170127)わかりやすいAWSサービス名、Rails DBは便利、TruffleRubyの驚異的速度ほか


つっつきボイス: 「前回取り上げたとき結構評判よかったですね、これ」「あー、Railsエンジン(マウンタブルエンジン)になってて、マウントするとデータベースのCRUDが出るヤツか」

参考: Rails エンジン入門 | Rails ガイド

phpmyadminとかpgadminよりはイケてそうかな: ただこの種のマウンタブルエンジン型のデータベース管理ツールは、マウントするとあくまでRailsのサーバーのワーカー上で動くので、たとえば死ぬほど遅いSQLクエリをこういうので投げるとワーカーが固まる❄️」「🙁」「逆にphpmyadminみたいに別プロセス/別スレッドで動く管理ツールなら、最悪DBは重くなってもUnicornやPumaとかまでは巻き添えを食わずに済む」「そっか!」「もちろん、たとえばPumaをマルチプロセス/マルチスレッドで運用してればそこまでには至らないけど、ワンプロセス/マルチプロセスだとCPU割り当て時間が短くなってしまうかもね」「なるほどー😲」「こういうツールはいろいろ便利だけど、そこらあたりを念頭に置いて使いましょうということで😼」

RailsConf 2018の動画が出揃う(Ruby Weeklyより)

全87件という膨大なプレゼン数です。以下はDHHのキーノートスピーチ動画です。


つっつきボイス: 「これをコンプリートする人、いないでしょうね…」「ダラダラ流すぐらいしか思いつかんw: 最近ジムに通ってるからそのときにでも流すかな」「お😳、マシンエクササイズあたりですか?」「肩こりとかヤバいんで筋力取り戻しにかかってる😋」

私は道具使わない方向で腹筋と下半身鍛えてます。ドンピシャの動画がなかったので以下は適当です↓。

Railsのログ出力を無効にする方法(Hacklinesより)

コード1行のエントリでした。

見積もりは経験


つっつきボイス: 「Railsに限らないですね」「こればっかりはね、方法論はいろいろあれど、モノにするにはもう経験積みまくるしかないマジで」

PhusionのGDPR対応記事(RubyFlowより)

API設計の不確定性


つっつきボイス: 「とにかくAPIはどう使われるか事前には予測つかないから😆😆」「😆」「FacebookやGoogleですらあれだけAPIが変わりまくってるぐらいだし、レガシーAPIを廃止するのもほんと大変だし、長く運営するAPIサーバーほど設計難しす😭」

「Vue on Rails」やってみた


つっつきボイス: 「お、ちゃんとしたSPAっぽく見える😃: 参考になりそう」「Vuetify!」「いい名前!」「記事の最後にもあるように、RailsとVueの役割分担とバランスをどうするかですね: このあたりはまだまだ試行錯誤中だし」

参考: Vue.js Material Component Framework — Vuetify.js — Material Designベースのコンポーネントフレームワーク
参考: Vuex | Vuex とは何か? — 状態管理パターン + ライブラリ
リポジトリ: axios/axios — PromiseベースのHTTPクライアント


vuetifyjs.comより

Ruby trunkより

提案: Object#dupにブロックを渡したい

require 'uri'

module MyUri
  class << self
    def foo_uri
      base_uri.dup.tap { |e| e.path = '/foo' }
    end

    private

    def base_uri
      @base_uri ||= URI.parse('http://example.com')
    end
  end
end

つっつきボイス: 「おーなるほどワカル: 今はActiveRecordのcreateとかにもこれあるんで」「おー」「ActiveRecordのcreateとかbuildは、ブロックを渡すとこんな感じでデフォルト値を設定できる😋」「それなしだと今はtapしてやらないといけない」

参考: DevDocs — Ruby on Rails 5.2 / ActiveRecord::Relation#create

# DevDocsより
users = User.where(name: 'Oscar')
users.create # => #<User id: 3, name: "Oscar", ...>

users.create(name: 'fxn')
users.create # => #<User id: 4, name: "fxn", ...>

users.create { |user| user.name = 'tenderlove' }
# => #<User id: 5, name: "tenderlove", ...>

users.create(name: nil) # validation on name
# => #<User id: nil, name: nil, ...>

参考: Rubyリファレンスマニュアル instance method Object#tap (Ruby 2.5.0)

片側のみのComparable#clampが欲しい

# 同issueより
# with clamp
chain.of.calculations.clamp(0..)

# without clamp
v = chain.of.calculations
v < 0 ? 0 : v

# or, with yield_self (renamed to then)
chain.of.calculations.then { |v| v < 0 ? 0 : v }

つっつきボイス:clamp(0..)みたいに片方が開いたRangeオブジェクトを渡したいってことか: でないと範囲を手書きしたり、yield_selfしたりしないといけない、と: 気持ちはワカル」「yield_self😳?!」「何かで使ったことあった」「2.5から入ったんですね」

参考: Rubyリファレンスマニュアル instance method Comparable#clamp (Ruby 2.5.0)

self を範囲内に収めます。
self <=> min が負数を返したときは min を、 self <=> max が正数を返したときは max を、 それ以外の場合は self を返します。

12.clamp(0, 100)         #=> 12
523.clamp(0, 100)        #=> 100
-3.123.clamp(0, 100)     #=> 0

'd'.clamp('a', 'f')      #=> 'd'
'z'.clamp('a', 'f')      #=> 'f'

参考: instance method Object#yield_self (Ruby 2.5.0)

selfを引数としてブロックを評価し、ブロックの結果を返します。

# 同上
"my string".yield_self {|s| s.upcase }   # => "MY STRING"
3.next.yield_self {|x| x**x }.to_s       # => "256"

参考: Ruby 2.5 の yield_self - Qiita

代入によるguard構文を後置のifでも使いたい

# 同issueより
def test
  if result = calculate_result  # 動く
    return result
  end

  ...
end
# 同issueより
def test
  return result if result = calculate_result # 動かない

  ...
end

[Ruby/Rails] 例外で深くなったネストをGuard Clauseですっきりさせる


つっつきボイス: 「これはやめといた方がいいと思うし: Rubocopに怒られるし」「😵」「ifの条件式に代入文を書かないことというヤツです」

Rubyスタイルガイドを読む: 文法(6)演算子など

Ruby

Ruby 2.5のブロックパラメータで使えるlazy proc

# 同記事より: Ruby 2.5の場合
irb> require 'benchmark'
  => true
irb> def greet
irb>   yield
irb> end
  => :greet
irb>
irb> def greet_with_welcome(&block)
irb>   puts 'Welcome'
irb>   greet(&block)
irb> end
  => :greet_with_welcome
irb>
  irb> Benchmark.measure { 1000.times { greet_with_welcome { 'BigBinary' } } }
Welcome
Welcome
...
...
...
  => #<Benchmark::Tms:0x00007fa4400871b8 @label="", @real=0.004612999997334555, @cstime=0.0, @cutime=0.0, @stime=0.001524000000000001, @utime=0.0030690000000000023, @total=0.004593000000000003>

つっつきボイス: 「パフォーマンスが向上するみたいですね」「なるほど、procをyieldしたものをまたyieldするときに、1回目の評価で展開するんじゃなくてlazyにやってくれるってことか😋」

「これはRubyProfのようなプロファイラで解析した結果に何らかの形でかなり影響する可能性がありますね」「😮」「主にライブラリあたりで、どこがボトルネックになっているかみたいな解析結果に影響しそうに思える: Railsアプリぐらいの規模になるとそんなに変わらないかもですが😼」

依存性の注入(DI)はテストで必要か?(Hacklinesより)

Testdouble社のブログです。


testdouble.comより

Hacklinesの調子が悪くて、なぜかリンクをクリックすると500エラーになったので、タイトルでググりました。

# 同記事より
require 'rspec'
require_relative 'shirt_v2'

describe Shirt do
  it "doesn't buy shirts when there are none left" do
    fake_inventory = Object.new
    fake_inventory.define_singleton_method(:check_availability) { |_product_code| false }
    fake_purchaser = spy
    shirt = Shirt.new('small', fake_inventory, fake_purchaser)

    result = shirt.buy!

    expect(result).to eq(false)
    expect(fake_purchaser).not_to have_received(:purchase_item).with('abc123')
  end

  it "buys a shirt when there are shirts available" do
    fake_inventory = Object.new
    fake_inventory.define_singleton_method(:check_availability) do |product_code|
      product_code == 'abc123'
    end
    fake_purchaser = spy
    shirt = Shirt.new('abc123', fake_inventory, fake_purchaser)

    result = shirt.buy!

    expect(fake_purchaser).to have_received(:purchase_item).with('abc123')
    expect(result).to eq(true)
  end
end

参考: xUnit Test PatternsのTest Doubleパターン(Mock、Stub、Fake、Dummy等の定義) - 千里霧中


つっつきボイス: 「testdoubleってDIですよね: テストにどんな種類があるか、みたいな話はt_wadaさんのスライドか何かで見たなー」「testdouble自体よくわかってなかった…😓」「あ、これこれ↓: スライドの2ページ目」

「著者は自社であるtestdoubleが提唱する「Arrange, Act, Assert」というテスティングパターンが好みだそうです」「そういうコードならDIでやっていいんじゃないかな」

参考: Arrange Act Assert · testdouble/contributing-tests Wiki

  • Arrange: テストのセットアップで必要なものはすべてここで記述する
  • Act: テスト中のsubjectの振る舞いを記述する
  • Assert: subjectの振る舞いが期待どおりかどうかを戻り値や副作用で検証する(spyやmockを使用)

Rails tips: RSpecの「スパイ(spy)」の解説(翻訳)

「ところでmockとかstubって、小さな機能をテストする分にはいいんだけど、でかい機能をテストしづらいですよね」「あー」「そもそもmockやstubはテスト対象のメソッドを分割して機能を小さく保つことが前提なんで、メソッドがでかくなると途端につらくなる😭: 本当にテストできてるのか?って不安になるし、mockオブジェクトがどえらく複雑になって本末転倒感出たり」

「なんやかやで、コンポジットするにしろDIするにしろ、クラスなりメソッドなりの機能を小さく保っておかないとつらくなるのはどのやり方でも変わらないなと思うわけです」「確かにー」

re2: 高速/安全/スレッド良好を謳うGoogle製正規表現ライブラリ

# mudge/re2/より
$ irb -rubygems
> require 're2'
> r = RE2::Regexp.new('w(\d)(\d+)')
=> #<RE2::Regexp /w(\d)(\d+)/>
> m = r.match("w1234")
=> #<RE2::MatchData "w1234" 1:"1" 2:"234">
> m[1]
=> "1"
> m.string
=> "w1234"
> m.begin(1)
=> 1
> m.end(1)
=> 2
> r =~ "w1234"
=> true
> r !~ "bob"
=> true
> r.match("bob")
=> nil

参考: 開発者に聞く、Google Chromeが目指すもの - @IT — 作者Russ Coxについて言及されています
参考: Goの正規表現エンジンを使ってファジング用ツールを書いてみる - YAMAGUCHI::weblog


つっつきボイス: 「正規表現厨としては見逃せないので😤(初めて見たけど)」「C++で書かれてる」「聞き覚えある: re2」「ラッパーもRuby以外にいろいろな言語向けのがあるけど、Infernoって?」「あれじゃないっすか?Plan 9 OSの後継のInferno OS」「何それ🤣言語じゃなくって?」

参考: Plan 9 from Bell Labs - Wikipedia

Plan 9の由来である「Plan 9 from Outer Space」です↓。

Inferno(煉獄)って名前、個人的に好きです。

参考: Inferno (オペレーティングシステム) - Wikipedia

Infernoといえばダンテ「神曲」(神聖喜劇の方が意味が近いらしい)ですが、まるでLinuxのシステム階層かTCP/IP階層か何かを逆さにしたようなピラミッドチャート的概念を伴う地獄世界が登場します。最下層はカーネルではなく、魔王が氷漬けにされています。


Wikipedia Botticelli Chart Of Dantes Hell(パブリックドメイン)より

参考: 神曲 - Wikipedia

ダンテ「神曲」は単なる古典ではなく、当時は一方言に過ぎなかったトスカーナ地方の言葉で書かれていたのが、そのまま現代イタリア語のリファレンスとして使われるようになったのだそうです。つまり現代イタリア語の究極実装とライブラリがいきなり出現したような塩梅です。イタリアの子どもたちは必ず神曲を学ぶと何かで読んだ覚えがあります。

to_ito_intとかってどう違うの?

# 同質問の回答より
1.to_s              # returns "1"
Object.new.to_s     # returns "#<Object:0x4932990>"
1.to_str            # raises NoMethodError
Object.new.to_str   # raises NoMethodError

{1,2}.to_a      # returns [[1, 2]], an array that describes the hash
{1,2}.to_ary    # fails, because a hash is not really an array.

Implicit vs explicit type conversions in Ruby (to_h/to_hash and others)の参考文献にあったStackoverflowの議論です。


つっつきボイス: 「おろ? {1,2}.to_a…動かないし、そもそもコードおかしくね?」「[]の打ち間違い?」(しばらく一同で試行錯誤)

「これだっっっ!↓」「=>って…」「この回答、17件も『いいね』されてるのに😓」

{1 => 2}.to_a
# => [[1, 2]]

ここで録画が終わってしまったので、以後のつっつきは軽めとなります🙇。

追記

以前のRubyでは動いたのだそうです。

「Gaijin Engineer in Tokyo」がご本人の手で日本語化

3月のウォッチでご紹介した記事です。

週刊Railsウォッチ(20180323)Rails 5.2.0 RC2リリース、「サーバーレスなRubyが欲しい」、capybara風JSテストフレームワークCypressほか

同じ方による新作「東京の白人特権階級」も気になります。

クラスやメソッドの命名をどうするか


つっつきボイス: 「この間タバコ中に、ネット上の英語シソーラスだとITに関係ない語がいっぱい出てきて不便だという話になったんですけど、クラスやメソッドの名前考えるときって、シソーラス使います?」「ものすごくよく使いますね🧐: 既存の名前と衝突せずに、かつ的確な名前を付けたいと思ったらシソーラスないとつらいし、使うべき」「ですよね😃: ちなみにどのシソーラス使ってます?」「まずはMacに内蔵されてるOxfordのシソーラスからかな↓」

「以下の記事にもあるんですけど、開発中のつらいタスクの半分を占めているのが『命名』でした」

雑談よりですが、英語圏を含むヨーロッパのアルファベット圏の多くでは、文章において(用語ではない)同じ語の繰り返しを嫌がる傾向があります。たとえば「大佐が」「大佐の靴を履き」「大佐の葉巻を吸いながら」「大佐の家に戻った」みたいな所有格がベタベタの書き方は、特殊効果を狙っているのでもない限り「教養がない」とされるんだそうです。

代わりに「大佐は」「その男は」「彼は」みたいに使い分けようとします。日本語で言うと、「〜です。」みたいな同じ語尾を何度も繰り返すのを嫌がるのと似た感覚かもしれません。

日本ではシソーラスを積極的に使う人をあまり見ないのですが、そういうわけでアルファベット圏ではシソーラスはむしろないと文章を書くのも大変みたいです。ちなみに以下の日本語シソーラスはめちゃめちゃ優秀で愛用してます👍。


renso-ruigo.comより

deprecateしたAPIをparser gemで書き直す(Ruby Weeklyより)

s(:send,
  s(:send, nil, :client), :read_events_backward,
  s(:str, "Order$1"),
  s(:hash,
    s(:pair,
      s(:sym, :limit),
      s(:int, 5)),
    s(:pair,
      s(:sym, :start),
      s(:sym, :head))))
client.read_events_backward('Order$1', limit: 5, start: :head)
      ~ dot                         
       ~~~~~~~~~~~~~~~~~~~~ selector                         ~ end
                           ~ begin                                       
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression

つっつきボイス: 「deprecateされた機能の書き換えを、parser使って構文解析することでやってるみたいですね」「だからS式出力してるのか…😮」「😮」

Hawker: GitHubやTwitter向けAPI不要スクレイパーgem

# 同リポジトリより
profile = Hawker.get("https://github.com/rubyhero")
profile.username # => "rubyhero"

profile = Hawker.get("https://twitter.com/pdabrowski_k1")
profile.name # => "Paweł Dąbrowski"

つっつきボイス: 「API不要ということはAPIのためのユーザー登録しなくていいので、ありがたい時がありそう😀」

愛すべき8つのgemと「IceNine」(Hacklinesより)


つっつきボイス: 「とりあえず知らないgemはないかな?と思ったけど」「Timecopは似たようなものがActiveSupportにもあるけど、少しだけ書きやすくなる」「ice_nineって?」「このgemの動作は知らないんですが、この名前は一発でわかりました: カート・ヴォネガットの『猫のゆりかご(Cat’s Cradle)』という小説に出てくるSFっぽい架空アイテムで、黒鉛とダイヤモンドみたいに通常の氷と結晶の相(phase)が異なるアイスナインをうっかり海に落っことすと、一瞬で世界中の海が常温のまま海底まで氷になっちゃうという究極の絶滅兵器」「はーなるほど!だからdeep_freeze↓😀」「カート・ヴォネガット、他の小説もユーモラスで哀愁があって大好き😍」

# dkubb/ice_nineより
require 'ice_nine'

# Deep freezes most kinds of objects
hash   = IceNine.deep_freeze('a' => '1')
array  = IceNine.deep_freeze([ 'a', 'b', 'c' ])
range  = IceNine.deep_freeze('a'..'z')
struct = IceNine.deep_freeze(Struct.new(:a, :b).new('a', 'b'))
object = IceNine.deep_freeze(Object.new)
user   = IceNine.deep_freeze(User.new(name: 'dkubb'))

# Faster deep freeze that skips deep-freezing frozen objects
object = IceNine.deep_freeze!(Object.new)

# Add core extension for Object#deep_freeze (not required by default)
require 'ice_nine'
require 'ice_nine/core_ext/object'

object = Object.new
object.deep_freeze

アイスナインは、日本での「タケコプター」ぐらいには米国で知られている感じです。

この解説書↓はネタバレを恐れずどしどしあらすじを書いているので、古典SFを知るにはとっても便利です😋。

mruby/cのロゴが決定


つっつきボイス: 「”c”が後ろに付くmruby/cが出力するバイナリは、確かそのままROMに焼けるんですよ」「おー😀」

その他Ruby


https://twitter.com/hsbt/status/999262359372754946

クラウド&コンテナ

AWS IoT Enterprise Button

参考: AWS IoT 1-Click の概要 – 任意のデバイスに AWS Lambda トリガーをワンクリックで作成


追いかけボイス: 「ちなみに日本では売ってないっぽい: デバイスがあれば使えはするらしき(AWS Management Console側は対応してる様子)」

AWSのベアメタルサーバ「i3.metal」が正式サービスに


先行ボイス: 「AWS、割と前から実質ベアメタルに近い環境はありましたね」「たしか前そう伺った気が」「とはいえ完全なベアメタル環境だとやれることも違うので、意味はある(ドライバ開発とか」

以下の記事にも載っている「Amazon EC2 Dedicated Hosts | AWS」がそれですね。

ベンチマークの詳しい理解と修正のコツ(翻訳)

一部領域ではOneDriveが一番人気説


つっつきボイス: 「OneDrive、Windowsの画面で一番いい位置占めてるし🤔」「😆」

その他クラウド&コンテナ



SQL

OmniDB


同リポジトリより

SQLがNoSQLに勝利した理由

How to scale PostgreSQL 10 using table inheritance and declarative partitioningの中で引用されていた記事です。

Timescaledb: オープンソースの大規模時系列データベース


同サイトより


つっつきボイス: 「time-scaleって時系列でいいんですよね?」「もちろん: 以前研究で時系列データベースとお付き合いしてたこともあったので」「この時計と虎をあしらったロゴかっこいいですね🐯」

同社の記事『How to scale PostgreSQL 10 using table inheritance and declarative partitioning』を近々公開します。

JavaScript

Chrome Devtoolsの「Network Search」とは

react-native-domとは

参考: react-native-dom の何がすごいのか - Qiita

JavaScriptでFirebase認証

参考: Firebase — 公式サイト
参考: 「Google丸投げ」でiOSアプリ開発が恐ろしくラクになる!Firebaseの使い方 - WPJ

CSS/HTML/フロントエンド

Bootstrap 4関連

毎週木曜日のBPS社内勉強会で言及されていた資料をメモします。

See the Pen Pure CSS Accordion by Rau (@raubaca) on CodePen.

ChromeブラウザのHTTP締め出し間もなく開始


blog.chromium.orgより

HTTPSが当たり前という流れになるようです。

Chromeでピクチャインピクチャ

MacだとFenêtreがありますが、これならLinuxでもできる?

参考: [Picture in Picture] Show video in OverlayWindow. (I01cc0af0) · Gerrit Code Review — マージコミット

その他CSS/HTML/フロントエンド



言語よろずの間

Rustの公式ドキュメント日本語版

600ページ近い大作です。そして翻訳の質も極上です。

Elmとは

参考: Elmというミニマムでフレームワークにもなる関数型altJS言語を触ってみよう!!! - Qiita

プログラミングとプログラミング的思考の違い


同記事より

その他言語



その他

GTFSとは

参考: General Transit Feed Specification - Wikipedia

らくらくTensorFlow


同サイトより

「shelling peas」(エンドウ豆なんかの鞘を剥く)という表現が気になります。

大著「Linux Inside」が公開

その他のその他





これ本当にテスターとかシンクロスコープにもなるなら、欲しいです。



実はRだけではなく、Lも、日本語の「らりるれろ」とは全然発音方法が違うことに気づくのが重要です。どっちの発音も日本語には存在しません。
日本語で「らりるれろ」と発音しても「la li lu le lo」には絶対ならないというあたりに、日本語と英語の距離の遠さを痛感します。

義務教育でこれを指摘してないどころか、L音を「らりるれろ」で指導して済ませているのはマズいと思います。

実はLの音は、Lの音を出す「直前の」音(というか口の中の形)の方が遥かに重要です。

これをすごく無理やりたとえると、ゲロの吐き始めの最初の音がLに近い音です。舌の先のやや裏側を歯の裏に軽く当てて、口は閉じずにやや左右に開いて、ゲロを吐きそうになる酔っぱらいの真似をしてみてください。下の動画のように口を閉じてはいけません。

その音が出せるようになったら、そこに母音を足します。

この謎の先行音を出せれば、その後にくっつく実際のLとか他の子音やら母音とかは本当に何でもいいぐらいです。

尋ねたわけではありませんが、英語圏の人ならそのプレフィックス的な謎音の方がむしろLの音だよと言うでしょう。今までわざと書きませんでしたが、この謎の先行音こそがL子音です。

これでやっと、 will とかlittleがなぜああいう発音なのかが理解できます。どっちも、いわゆる L の本体の音を出してない: 上で言う謎の先行音だけを使ってます。特にlittleの2つめのlは、この子音がラストを飾ります。

お食事中の方、失礼いたしました🙇。

番外

健康情報

乗り物特集

参考: 二酸化炭素を上空にまき散らさない「電動航空機」の開発が進む - GIGAZINE
参考: 世界初の排気ガスゼロの「完全電気駆動フェリー」がノルウェーで登場 - GIGAZINE
参考: 滑ったバイクを逆噴射で立て直すスラスター安全装置、独Boschが発表。カーブの浮き砂利に効果 - Engadget 日本版

鑑定やいかに

バイオリニストを対象としたストラディバリのバイオリンと安価なバイオリンの覆面テスト判定率は、偶然の場合とほとんど変わりなかった云々。

個人的には、いい楽器は言ってみればIDEみたいなもので、いい音を「楽に出せる」ぐらいのメリットしかないと思ってます。上手な人は何を弾いてもいい音がするという逆説的な「弘法筆を選ばず」現象にたくさん遭遇しました。

参考: ソーカル事件 - Wikipedia

銀河から酸素を検出

タコやイカは地球外由来?

そういえば人間を含む多くの動物の眼球では、網膜の表側(光が当たる方)に神経がワイヤリングされている一方、イカの眼球は網膜の裏側からワイヤリングされているそうで、裏側配線の方が普通に考えて合理的だよなと思ったことがありました。


Ask A Science Blogger: Which parts of the human body could you design better? – Living the Scientific Life (Scientist, Interrupted)より

参考: 「タコやイカは地球外生物の影響から生まれた」とする説を科学者グループが発表 - GIGAZINE

参考: あの動物はどんな目を持ってるの? 生き物たちの目の種類を調べてみた | 目をゆる〜くマジメに考える 目ディア

こちらのツイートのスレも面白い内容になっています。

オープンオフィスでの集中を保つには

参考: 仕切りのない「オープンオフィス」がもたらす不快感を軽減するにはどうすればいいのか? - GIGAZINE

遊星歯車

そういえば最近はplanetを遊星と訳すこともめったになくなりましたね。


つっつきボイス: 「こういうのね、ずうっと眺めても飽きない⚙️」

参考: 遊星歯車機構 - Wikipedia

鉄を作る

つい見入っちゃいました。水たまり表面の鉄バクテリアを集めて製鉄するとか思いもよりませんでした。


つっつきボイス: 「このゆーちゅーばーさん有名で、相当お金持ちって聞いた気がする」「道理で身体のどこにも蚊に刺された痕がない😝」


今週は以上です。来週のRubyKaigi 2018でお会いしましょう!

おたより発見

週刊Railsウォッチ(20180518)Paperclip開発終了、RailsアプリをGDPR準拠に、optparseはやっぱりいい、Rubyの`super`ほか

もりだくさんでありがたし

2018/05/22 11:53

バックナンバー(2018年度)

週刊Railsウォッチ(20180518)Paperclip開発終了、RailsアプリをGDPR準拠に、optparseはやっぱりいい、Rubyの`super`ほか

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Hacklines

Hacklines

Frontend Focus

frontendfocus_banner_captured

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ