Tech Racho エンジニアの「?」を「!」に。
  • 開発

週刊Railsウォッチ(20190624-1/2前編)6.1でActionView::Componentが入る、RuboCopのRuby/Railsスタイルガイドサイト、RailsガイドProプラン/Teamプランほか

こんにちは、hachi8833です。先週金曜日夜は銀座Rails#10でのmorimorihogeさんの発表を写真撮影しておりました。

RDBMSのVIEWを使ってRailsのデータアクセスをいい感じにする【銀座Rails#10】

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください

お知らせ: 第12回公開つっつき会(無料)

開始以来ついに1年目を迎える第12回目公開つっつき会は、7月4日(木)19:30〜にBPS会議スペースにて開催されます。皆さまのお気軽なご参加をお待ちしております🙇。

Rails: 先週の改修(Rails公式ニュースより)

主に公式情報から見繕いました。

6.1にActionView::Componentがやってくる

# actionview/lib/action_view/helpers/rendering_helper.rb#L27
      def render(options = {}, locals = {}, &block)
        case options
        when Hash
          in_rendering_context(options) do |renderer|
            if block_given?
              view_renderer.render_partial(self, options.merge(partial: options[:layout]), &block)
            else
              view_renderer.render(self, options)
            end
          end
        else
-         view_renderer.render_partial(self, partial: options, locals: locals, &block)
+         if options.respond_to?(:render_in)
+           options.render_in(self, &block)
+         else
+           view_renderer.render_partial(self, partial: options, locals: locals, &block)
+         end
        end
      end

なぜか公式の更新情報には入ってませんでしたが、プルリクのスレを見るとみんな超大喜び&大盛り上がりしているようです。実装はまだ始まったばかりのようですが、PRメッセージにがっつり構想が書かれています。Rails 6.1の真打ちの予感です(6はさすがに間に合わないそうです😅)。

プルリクの主はGitHubの中の人の@joelhawksleyさんです。

参考: Joel Hawksley | Boulder, Colorado


つっつきボイス:「今日社内Slackで盛り上がったActionView::Component、やっぱり6.1からだそうです」「やはり😆まだ遠いかな〜」

「RailsConf 2019の以下の発表が先行していたようですが、このスライドは喋りの演出に最適化されてて単独だと読みづらかったのでウォッチではスキップしてました😆」

「Reactのコンポーネントみたいなものを目指してるのかな?」「お〜、こんな感じに書けるようになるっぽい↓😋」

「どうやらまたRails Wayに寄せてきた感あるかも😆」「フロントエンジニアに何言われるかと思うと🤣」「Reactとかの方もそれはそれで将来もっと書きやすくなるかもしれないし🤔」「ここはとりあえず見守っておこう🤣」「🤣」

ActionView::Componentは「新奇なアイデア」からは程遠いものである。Rubyにも以下のようなビューコンポーネントの有名な実装はあるが、この他にもある。
同PRより

「上のgemたちがActionView::Componentと同類ということみたいです」「コンポーネントっぽくしたいならこのあたりに似てくるでしょうね☺️」

「PRのスレを見てると、コンポーネント内のファイル配置↓をどれにしようかな〜ってみんなキャッキャウフフしてますね❤️」「遠足の前の日ですか😆」「Railsだけでコンポーネントやれるというのはいいかも😋」「採用するかどうかは、まプロジェクト次第ということで😆」

app/views/components/
  - my_component/
    - component.js
    - component.css
    - component.rb
    - template.html.erb
    - template.html+mobile.erb
app/views/components/
  - my_component/
    - component.rb
    - template.html.erb
    - template.html+mobile.erb
app/views/components/
  - my_component.rb
  - my_component.html.erb
  - my_component.html+mobile.erb

「前回のウォッチで話したMicro Frontend(ウォッチ20190618)にも通じるんでしょうか?」「まそんな感じですね☺️」

「そういえば、モノは違うけどRails 1.2にこんなのあったよね↓とPRに書いてる人がいました」「あ〜なるほど、Webフレームワークってこういうコンポーネントみたいなものって昔からあって、自分もPHPのSymfonyでそういうの使いましたよ」「そうでしたか!」


symfony.comより

Symfony 1.xのコンポーネント

「ただSymfonyのコンポーネントは、たしかレイアウトがあって、その中にコンポーネントを配置できて、コンポーネントの中にはさらにスロットを配置するという、いわゆるビューに階層を作れるアーキテクチャでしたね🧐」「お〜」「たとえばSideMenuコンポーネントの中にRankingスロットみたいなのをいろいろ配置できるヤツで、自分が見たSymfonyのコンポーネントはそういう趣き: 今はどうなってるか知りませんが😆」「😆」

参考: Symfony - Wikipedia

「軽くググってみるとSymfony 1.x系みたいだから今はなさそうかな」「どうもそんな感じですね」「あの頃Symfony 1系の中のコードまで読んでたな〜」

参考: 第7章 - ビューレイヤーの内側 (1_4)

「そうそう、Symfony 1.xのスロットはこんな感じだった↓: 全体テンプレート、ここではHeadlines SidebarというHeadlines部分テンプレート(partial)、さらにスロットを置けるようなつくりになってます」「う、ややこしい...😅」



symfony.com/legacyより


「Rails 6.1に入るActionView::Componentは、これらよりはフロントエンドに寄せた感じというか、Web Componentsレイヤーのコンポーネント的な位置づけなんでしょうね☺️」「RailsでWeb Componentsすることになるんだろうか😆」

参考: Web Components | MDN

ダイレクトアップロードでmirrorサポート

  • mirrorサービスでダイレクトアップロードをサポート。
    新しいファイルはprimaryサービスに直接アップロードされる。ダイレクトアップロードされたファイルはレコードにアタッチされ、バックグラウンドジョブがキューに入って各セカンダリサービスにコピーする。
    ジョブをミラーリングする処理で使われるキューはconfig.active_storage.queues.mirrorで設定する。デフォルトは:active_storage_mirror
    同Changelogより
# activestorage/lib/active_storage/engine.rb#L19
module ActiveStorage
  class Engine < Rails::Engine # :nodoc:
    isolate_namespace ActiveStorage
    config.active_storage = ActiveSupport::OrderedOptions.new
    config.active_storage.previewers = [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
    config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer, ActiveStorage::Analyzer::VideoAnalyzer ]
    config.active_storage.paths = ActiveSupport::OrderedOptions.new
    config.active_storage.queues = ActiveSupport::OrderedOptions.new
    config.active_storage.queues = ActiveSupport::InheritableOptions.new(mirror: :active_storage_mirror)

つっつきボイス:「なるほど、そっちの意味のmirrorね☺️: ストレージサービスを複数(GoogleドライブとS3とか)使って、どちらにでもアップロードできるようにするということのようだ」「たしかにこれは欲しいヤツ😋」「マルチリージョンでアップロードできるようになったらうれしい😍」

ActiveRecord::Relationのプリロードを修正

# activerecord/lib/active_record/associations/preloader/association.rb#L29
        def records_by_owner
-         @records_by_owner ||= preloaded_records.each_with_object({}) do |record, result|
+         # owners can be duplicated when a relation has a collection association join
+         # #compare_by_identity makes such owners different hash keys
+         @records_by_owner ||= preloaded_records.each_with_object({}.compare_by_identity) do |record, result|
            owners_by_key[convert_key(record[association_key_name])].each do |owner|
              (result[owner] ||= []) << record
            end
          end
        end

つっつきボイス:「❤️が山盛りなのは『Rubyエライ!』ということかしら😆」「compare_by_identity?」「お〜、Hashインターフェイスにcompare_by_identityというのがあるのか!」


同PRより

参考: instance method Hash#compare_by_identity (Ruby 2.6.0)

ハッシュのキーの一致判定をオブジェクトの同一性で判定するように変更します。
デフォルトでは、キーのオブジェクトによっては内容が同じならキーが一致しているとみなされますが、より厳密に Object#object_idが一致しているかどうかを条件とするようにselfを変更します。
selfが変化する破壊的メソッドです。
docs.ruby-lang.orgより

「ドキュメントにあるように、ハッシュのキーの一致判定をオブジェクトの同一性で判定するように変更するメソッドなのね」「おぉ?」「普通だとハッシュのキーはvalueで判定されるんですが、compare_by_identityを呼ぶとハッシュのステータスが変わって、オブジェクトが同一でないと一致しないようになるという」「compare_by_identityっていう名前だから同一性で比較するメソッドかと思ったら、同一性比較のためにハッシュを改変するってちょっとコワい😅」

「このプルリクは元々#36396↑の修正のためということで...なるほど、関連付けがプリロードされると同じレコードがインメモリでコピーされて重複することがあったから、それを扱えるようにcompare_by_identityを使ったということらしい🧐」「おぉ」「レコードが複製された場合は違うものとみなされないと困るからでしょうね」「先週もマルチDB絡みで似たような話があった気がするので、その流れなのかも?」「よくぞ見つけた感👍」

Active Recordのスキーマキャッシュのdeduplicate

# activerecord/lib/active_record/connection_adapters/deduplicable.rb#L3
+module ActiveRecord
+  module ConnectionAdapters # :nodoc:
+    module Deduplicable
+      extend ActiveSupport::Concern
+
+      module ClassMethods
+        def registry
+          @registry ||= {}
+        end
+
+        def new(*)
+          super.deduplicate
+        end
+      end
+
+      def deduplicate
+        self.class.registry[self] ||= deduplicated
+      end
+      alias :-@ :deduplicate
+
+      private
+        def deduplicated
+          freeze
+        end
+    end
+  end
+end

つっつきボイス:「これももしかするとマルチDB絡み?」「どちらかというとメモリ削減のリファクタリングっぽい: まあこれまでシングルトンだったのがマルチになってくるといろいろやらないといけないでしょうけど」

Deduplicableっていうモジュールが増えてますね」「レオナルド・デュカプリオみたい😆」「早口言葉😆」「dereferenceとかも😆」

小品: エラー画面をレスポンシブに


同PRより


つっつきボイス:「あは、なるほど😆」「こういう修正はやっぱりいいっすね~😍」「地味だけどうれしい修正」「意外に今までやってなかったんですね☺️」「しかも修正はviewport入れてCSSをちょいちょいっと直しただけ😆」「それでやれる修正ですし☺️」「グッジョブ!👍」「誰かがやってくれるとみんなが喜ぶヤツ😂」

# actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb#L2
<html lang="en">
<head>
  <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Action Controller: Exception caught</title>
  <style>
    body {

Rails

RubyスタイルガイドのリニューアルとRailsスタイルガイド(Ruby Weeklyより)


rails.rubystyle.guideより


rubystyle.guideより


つっつきボイス:「RuboCopの人たちがRubyとRailsのスタイルガイドサイトを立ち上げたそうです」「へぇ〜」「しかも私全然気が付かなかったんですが、どちらもしっかり日本語化されてます🇯🇵」「こういうのはコントリビュートしやすい分野ですよね☺️」

【保存版】Rubyスタイルガイド(日本語・解説付き)総もくじ

「以前TechRachoで出していたRubyスタイルガイドの翻訳プラスアルファ記事↑があってPV稼いでくれてますけど、今後は上のサイトがメインになるのかな...😢」「上のサイトの方が新しい?」「まだちゃんと見てませんが何だか編成も変わってるみたいで、RuboCopのLayout部署とかその辺も最近変わってるからかも」

「日本語版の『ヴァリデーション・ファイル』って表記珍しい😆」「私はこの中黒使わないスタイルでやってるので割と気になります😆」「『ユーザー・フレンドリー』とかも😆」「まあ統一されていればいいんですけど、点があったりなかったりしたらちょっと😅」「英単語が切れてたらそこが中黒になるんでしょうけど☺️」「その割には『ヘルパーメソッド』に点がないし😆」

「ともあれ、日本語じゃないと読みたくない人たちにはありがたいと思いますね☺️」「あと困ったときに『とりあえずここ読め』という一次情報があるのもありがたいです😂」

「私も翻訳で常日頃悩んでるんですが、今後原文の差分を訳文でどう追いかけるのかなと😆」「ほんにそれ😆」「『とりあえず原文で読め』と🤣」「それが結局コスト一番低いし🤣」「翻訳版で地雷踏んだことがあるとだいたいそうなる🤣」「ちゃんとメンテされているとわかっている日本語ドキュメントならさらっと読むのに使ったりするけど、訳が間違ってるとか古いとかでいろいろハマった身としては、ね☺️」

Bounded Queueでアプリを短時間で復帰(Hacklinesより)


つっつきボイス:「Bounded Queues?」「お、これは中で詰まってるパターン↓ですね: キューがあふれてタイムアウト🕙」

Starting…
[0] 200 - 4.13 seconds elapsed
[1] 200 - 9.13 seconds elapsed
[2] 200 - 14.13 seconds elapsed
[3] 200 - 19.13 seconds elapsed
[4] 200 - 24.14 seconds elapsed
[5] 200 - 29.14 seconds elapsed
[6] 504 - 29.70 seconds elapsed
[7] 504 - 29.80 seconds elapsed
[8] 504 - 29.90 seconds elapsed
[9] 504 - 30 seconds elapsed
Took 30.0102 total, avg of 21.9242 in thread time, max 30, min 4.13

「こういうふうに時系列をちゃんと書いてくれているのはエライ↓👍」「たしかに〜」「教科書みたい」「できれば図にして欲しいけどっ😆」「TCPバッファリングの話もある」

00:00 — [A] Client sends request A to Server
00:01 — [A] NGINX buffers the HTTP request into memory and sends it to Puma
00:01 — [A] Puma accepts the connection, reads the request into memory and queues it
00:03 — [B] Client times out, sends request B to Server
00:04 — [B] NGINX buffers the HTTP request into memory and sends it to Puma
00:04 — [B] Puma accepts the connection, reads the request into memory and queues it
00:05 — [A] Puma starts processing the request, and responds with it to NGINX
00:06 — [A] NGINX throws the response away since the client closed the connection for A
00:06 — [B] Puma starts processing the request, responds with it to NGINX
00:07 — [B] Client receives the response for B

「NGINXをフロントにしてPumaを挟むとNGINXの方でいい感じにしてくれるという話」「ふむふむ」「Pumaでフロー制御までやるのは大変なので、NGINXのフロー制御周りの機能を使って、アプリケーションストリームだけPumaの方に流すとかそんな感じ☺️」

「そしてmax_conns=3にかかったら即座にエラーを返すようにしたということみたい」「なるほど!」「スレッドプールがフルになってたらどうせさばけないので😆」「諦めが肝心😆」「おそらくNGINXでPumaのスレッドの残数とかを参照して、フロントのNGINXがPumaのステータスに応じて空気を読むことで、Pumaがあふれていたら手前のNGINXのところでリクエストを止めようという話でしょうね」「Pumaの顔色がやばかったら助けてあげる感じですか🤢」

Starting…
[0] 200 - 4.13
[1] 200 - 9.14
[2] 200 - 14.14
[3] 502 - 0.01
[4] 502 - 0
[5] 502 - 0
[6] 502 - 0
[7] 502 - 0
[8] 502 - 0
[9] 502 - 0
Took 14.14 total, avg of 2.74 in thread time, max 14.14, min 0

参考: Module ngx_http_upstream_module

「ステータス502って何だったかな: Bad Gatewayか↓」「502でいいのかというのはあるけど😆、クリティカルなものでなければこれでやれるでしょうね☺️」「案件によっては実際こうしないとキューが無限にたまり続けちゃいますけど、こうしておけば、さばくべきものはちゃんとさばけるようになりますし」「さばけないものはさばけないなりに早めに諦めると😆」

参考: 502 Bad Gateway - HTTP | MDN

Railsガイド「Proプラン」「Teamプラン」


railsguides.jpより


つっつきボイス:「お、安川さんだ!」「私も翻訳で関わっているRailsガイドのProプラン(個人向け)とTeamプラン(法人向けアカウント管理機能と決済一元化など)で、通常のガイドはもちろん誰でも見られるんですが、有料だとこうやって例のAlgolia検索ショートカットキーが使えます😋」「お〜なるほど!」

インタビュー: 超高速リアルタイム検索APIサービス「Algolia」の作者が語る高速化の秘訣(翻訳)

「こういうのはいいですね〜❤️」「私も少し試す機会がありましたが、ありがたいです🙏」「自分はそんなに頻繁には使わないかもですけど😆、BPS社内のWebチームでみんなが使いたいということであれば試しに契約してもよさそうだし😋」「今度Webチームミーティングで軽く聞いてみましょう😀」

「今の自分はRailsを長く使っていて検索キーワードがだいたい身体に沁み込んでるので、どちらかというと今は高速なAPI検索が欲しいかも😋」「APIdockの記事↓にも書きましたけど確かに欲しいですね😋」「その意味では、RailsガイドのProプラン/TeamプランはRails始めて日が浅い人とか久しぶりにやる人に特に向いている感じですね👍」

Rails: APIdockがいつの間にかRails 5.2.3とRuby 2.6.3まで更新された

「APIのメソッドってときどき別のクラスやモジュールに引っ越したりしますけど、それを追うのって大変ですよね😢」「となると今だとそれを追えるのはAPIdockかな〜」

なお、本日以下の記事も公開されていますね。

参考: 🚀Railsガイド『Teamプラン』をリリース - YassLab 株式会社

truemail: メールアドレスのバリデータgem(RubyFlowより)

# 同リポジトリより
require 'truemail'

Truemail.configure do |config|
  config.verifier_email = 'verifier@example.com'
  config.whitelisted_domains = ['white-domain.com', 'somedomain.com']
  config.blacklisted_domains = ['black-domain.com', 'somedomain.com']
  config.validation_type_for = { 'somedomain.com' => :mx }
end

つっつきボイス:「メールアドレスをバリデーションしてくれるgemだそうです」「お〜なるほど!」「自分で書かない方がよさそうなヤツですよね😆」

「どうやらtruemailはメール送信時にも使えるようだ」「あ、そうみたい」「実際に到達可能なメールアドレスかどうかをMXとかに問い合わせてやってくれそう😋」「MXバリデーションってありますね」「メールが届きません疑惑ってよくあるから😆、そういうときに使えるかも」

その他Rails

つっつきボイス:「Stellerっていう認証方法をこれで初めて知りました」「名前はどこかで聞いたことあるかな🤔」「使ったことないけど😆」「ブロックチェーンでanonymousに認証するみたい」「それが真のanonymousかどうかだけど😆、ブロックチェーンでやる以上はノードが分散している限りはやれるということなんでしょうね☺️」

参考: StellarAuth - Authenticate using your Stellar account - Galactic Talk
参考: ブロックチェーン - Wikipedia



つっつきボイス:「@kamipoさんのこの話、まさによくあるヤツ☺️」「これはマイグレーションの手順の問題: めちゃデカいテーブルのマイグレーションって一瞬では終わらないので、ALTER TABLEでロックされないようにこういう手順にしたりしますね」「ふむふむ」「でも②を先にやっておかないとコケることがあるよという話」

「まず、①で足すカラムはNULL許容でなければいけません」「それから②の新規レコードをデフォルト値fillで先にデプロイして、その後で③をやらないといけない: でないとデフォルト値fillしている最中にまた新規レコードが作られるとNULLカラムが残っちゃう、すると④のときにコケる😇」

「レースコンディション(競合状態)を発生させないためには、③の前に②をやっておくことが重要: ③の後に②をやることも可能は可能なんですが、それならもう一回③をやってから④をやらないといけない」

参考: 競合状態 - Wikipedia

「まあ例えるなら、昔のLinuxシステムの電源を落とす前にsyncコマンドを3回入力するみたいなものです🤣」「あ〜あの習慣ですか🤣」「自分もsyncコマンド3回的に念のためもう一度やっておくことありますし: 何しろマイグレーションでコケると結構ショックでかいので😇」

参考: sync; sync; sync; haltの伝承 - Qiita

Ruby

injectable: Ruby向けDIライブラリ(RubyFlowより)

# 同リポジトリより
class MyClass
  include Injectable

  dependency :collaborator

  def call
    collaborator.submit!
  end
end
# 同リポジトリより
class PdfGenerator
  include Injectable

  dependency :wicked_pdf

  argument :html
  argument :render_footer, default: false

  def call
    wicked_pdf.pdf_from_string(html, options)
  end

  private

  def options
    return {} unless render_footer

    {
      footer: {
        left: footer,
      }
    }
  end

  def footer
    "Copyright ® #{Time.current.year}"
  end
end

# でこんなふうに使ったり
PdfGenerator.call(html: '<some html here>')
# wicked_pdf依存をオーバーライドしたり
PdfGenerator.new(wicked_pdf: wicked_pdf_replacement).call(html: '<some html>')

つっつきボイス:「以前も似たようなDI gemを見たことある気がするけど?🤔」「これは初めてでしたが、似たようなのいっぱいありそうではありますね😅」「dependency :collaboratorとかするといい感じにやってくれると」「gemでやるほどのものだろうかという気はしますけどっ😆」「initializeメソッドとか生やしてくれるんなら、まあとても使いたい人が使えばいいのかなと☺️」

参考: 依存性の注入 - Wikipedia

「以下もbehavesも趣旨が近いのかなと思ったんですが」「これはまた別のものっぽいですね😆」「やっぱり😅」

# 同リポジトリより
class Predator
  extend Behaves

  implements :hunt
end

class Prey
  extend Behaves

  implements :run, :hide
end

class Shark
  extend Behaves

  # Sharkは`Predator`でもあり`Prey`でもある
  behaves_like Predator
  behaves_like Prey
end

implementsとかあるあたりにJavaの匂いを感じる😆」「injectもできるところは上と似ていなくもないけど」「これを使って効果的に読みやすくなるかどうかはまた別かな〜: 既にこれでいっぱい書かれていて後の人はコピペすればできる、ぐらいになってればいいけど、新たにこれを入れようとはあまり思わないし😆」

Rubyのパイプライン演算子


つっつきボイス:「演算子、はじかれたっぽい😆」「話があちこちで進んでるっぽくて、今どうなってるのか時系列を追うのつらいです😭」「Matzの『積極的に読みにくさに貢献してますね』というコメント🤣」「『必要性が高くない』も🤣」「まあパイプライン演算子が入ったところで使う人は少なそうですけど☺️」

「パイプライン演算子は順番通りに書き下しっぽく書けるから、たとえばコマンドラインなんかでマルチラインで入力して、最後にCtrl-Dと入力すると実行されるみたいな使い方のときにいいかも」「あ〜それあるかも」「手元でスクリプトのRubyをcat -とかで開いて、そこにコピペして最後にCtrl-Dとか、そういうふうにできるんだったらあってもいいかも😋」「pryとかで使ったりとか」「まぁ使うかというと使わないかな〜😆」

「そしてmametterさんのパイプライン演算子の歴史、日英両方で書かれてましたね」「偉大な仕事!」

参考: パイプライン演算子の歴史 - まめめも
参考: A Brief History of Pipeline Operator - mamememo

「パイプライン演算子だとこういうふうに実行順どおりに書けますからね↓」「うんうん」「エディタでなら普通に書きますけど、シェルだとReturn押したら戻ってこれないし🤣」「そうそう🤣」「だからパイプラインでこうやってシェルで入力できるなら意外にいいかも?」「まあドット.で書いてもできますけどっ😆」「😆」

# 同記事より
astonishing_argument_x
|> fantastic_process_f
|> marvelous_process_g
|> wonderful_process_h

「外してるかもしれませんが、yield_selfことthenにこの|>記号当てたらだめかなって」「パイプライン演算子はメソッドをチェーンしたいという目的があるからyield_selfだとまた違うかな🤔」「やはり〜😅」「左から右に処理を書けるのはいいかも」

Ruby 2.5の`yield_self`が想像以上に何だかスゴい件について(翻訳)

OmniAuth::Apple(Ruby Weeklyより)


つっつきボイス:「さっそくAppleの匿名認証に乗っかってきた😆」

参考: アップル「匿名認証機能」がもたらす巨大衝撃 | スマホ・ガジェット | 東洋経済オンライン | 経済ニュースの新基準

その他Ruby

# 同回答より
class C
  private
  def private_method
  end
end

こういう質問への一次回答を読めてとてもうれしいです😂。


つっつきボイス:「endがないのはアクセス修飾子だから?、と思ったらC++に似せたのか!」「インデントも浅くて済むし」「そういえば先週privateの後のインデントってどうよって話になりましたけど(ウォッチ20190617)、Matzの回答に沿うならprivateの後の行はインデントを変えないのが正当?😆」「Matzはインデントしてない、やったね😋」「じゃこれで行きましょう😆」

Ruby trunkより

0.nonzero?nilを返す(Ruby Weeklyより)


つっつきボイス:「上のissueはRuboCop作者の以下の記事で知ったんですが、下の方が読みやすいです」「0.nonzero?がnilを返す😆」「1.nonzero?1を返す🤣」

# 同記事より
0.zero?
# => true
0.nonzero?
#=> nil
1.zero?
#=> false
1.nonzero?
#=> 1

「たぶんif文の中でif a = 1.nonzero?みたいに代入する形にするヤツで、1.nonzero?があれば自分自身を返して、なければnilを返すみたいな、Railsで言うpresence的な使い方なのかな、たぶんね😆」「実際Rubyのbooleanとして使う分には問題ないし☺️」「Rubyではnilfalse以外はtrueでしたね」

参考: Object.presence
参考: Railsのpresenceメソッドが便利


前編は以上です。

おたより発掘

バックナンバー(2019年度第2四半期)

週刊Railsウォッチ(20190618-2/2後編)決済の分散トランザクション、フロントエンドのMicro Frontendアーキテクチャ、GitHubのコードジャンプほか

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

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

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Hacklines

Hacklines


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。