週刊Railsウォッチ(20181029) 特集『肥大化したActiveRecordリファクタリング7つの方法』今ならどうなる?Redis 5のストリーム機能他

こんにちは、hachi8833です。遅ればせながら先週はGitHubの中の皆さまお疲れさまです。


つっつきボイス:「自分はあの日たまたまGitHubには触ってなかったんでそんなに影響なかったかな」「チームではハマった人もいたみたい」「私はGitHubでリポジトリを追加した後プッシュしたら半日何も出てこなくて、夜リロードしたらやっと出てきました🌙」

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

公開つっつき会のお知らせ

おかげさまで公開つっつき会の第4回の参加希望者が初めて6人になりました😂。定員を引き上げましたのでご安心を🙇。

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

公式の更新情報がなかったので、例によってコミットログから見繕いました。今回はますますドキュメントの更新が多くなっていてpreview-releaseを予感させ、その分改修は小粒な感じです。

ActiveJobテストヘルパーから返されるジョブインスタンスにdeserializeされた引数を含めるようにした

# activejob/lib/active_job/test_helper.rb#L615
      def instantiate_job(payload)
-       job = payload[:job].new(*payload[:args])
+       args = ActiveJob::Arguments.deserialize(payload[:args])
+       job = payload[:job].new(*args)
        job.scheduled_at = Time.at(payload[:at]) if payload.key?(:at)
        job.queue_name = payload[:queue]
        job
      end

つっつきボイス:「ActiveRecordをARと略すのはよくやるけど、ActiveJobはAJ☺️」「Ajaxかと思た」「payloadを加工しないでそのまま渡すようにしたと: 前は通らなかったキーワード引数がこれで通る↓」

# activejob/test/cases/test_helper_test.rb#L477
  def test_assert_enqueued_with_returns
    job = assert_enqueued_with(job: LoggingJob) do
-     LoggingJob.set(wait_until: 5.minutes.from_now).perform_later(1, 2, 3)
+     LoggingJob.set(wait_until: 5.minutes.from_now).perform_later(1, 2, 3, keyword: true)
    end
...

IN句の値がboundable?かどうかにかかわらずpre-checkingをlazyにした

#33844以降eager-loadingやpreloadingでidが大量かつ巨大な場合、値がconstructableかどうかというpre-checkで阻止されないようになった。しかしこのpre-checkはクエリ実行時ではなくリレーションのビルド時に型を評価していて、一部のアプリで期待どおり動作しないことがあった。
そこでpre-checkをできる限りlazyにするようにし、リレーションのビルド時に型評価が発生しないようにした。
同PRより大意

# activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb#L13
-     def visit_Arel_Nodes_In(*)
+     def visit_Arel_Nodes_In(o, collector)
        @preparable = false
+         if Array === o.right && !o.right.empty?
+         o.right.delete_if do |bind|
+           if Arel::Nodes::BindParam === bind && Relation::QueryAttribute === bind.value
+             !bind.value.boundable?
+           end
+         end
+       end
         super
      end

つっつきボイス:「boundable?ってタイトルでわからなかったけどメソッド名でした」「oって何だ?😆」「Go言語みたいなあっさりしたローカル変数名ですね☺️」「コードはSQLのINになるパラメータを渡したときの挙動を変更したようだ」

参考: 逆引きSQL構文集 - IN句を用いた副問合せ

「うん、bind if bind.value.boundable?ArrayHandlerからDetermineIfPreparableVisitorに移動して展開のタイミングを後ろにずらしたんですね」「2**63というめちゃでかい値でテストしてる↓⛰」「2の63乗!」

# activerecord/test/cases/bind_parameter_test.rb#L37
      def test_too_many_binds
        bind_params_length = @connection.send(:bind_params_length)
-       topics = Topic.where(id: (1 .. bind_params_length + 1).to_a)
+       topics = Topic.where(id: (1 .. bind_params_length).to_a << 2**63)
        assert_equal Topic.count, topics.count
      end

「ついでにテストコードも軽くリファクタリングされてreferencesを使うようになってる↓」

# activerecord/test/schema/schema.rb#L160
  create_table :citations, force: true do |t|
-   t.column :book1_id, :integer
-   t.column :book2_id, :integer
+   t.references :book1
+   t.references :book2
    t.references :citation
  end

追記2018/10/30: こちらもご指摘をいただきました。ありがとうございます!🙇

「そういえば修正前の(*)は引数を全部握りつぶす記法だというのをこの記事書いてて知りました↓」

Ruby2.5.xのパラメータの制約についてまとめてみた

MySQL 8.0.13で親テーブルへのアクセス権がない場合のエラーを追加

# activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb#L639
        def translate_exception(exception, message)
          case error_number(exception)
          when ER_DUP_ENTRY
            RecordNotUnique.new(message)
-         when ER_ROW_IS_REFERENCED_2, ER_NO_REFERENCED_ROW_2
+         when ER_NO_REFERENCED_ROW, ER_ROW_IS_REFERENCED, ER_ROW_IS_REFERENCED_2, ER_NO_REFERENCED_ROW_2
            InvalidForeignKey.new(message)
          when ER_CANNOT_ADD_FOREIGN
            mismatched_foreign_key(message)
           when ER_CANNOT_CREATE_TABLE
             if message.include?("errno: 150")
               mismatched_foreign_key(message)
             else
               super
             end
           when ER_DATA_TOO_LONG
             ValueTooLong.new(message)
           when ER_OUT_OF_RANGE
             RangeError.new(message)
           when ER_NOT_NULL_VIOLATION, ER_DO_NOT_HAVE_DEFAULT
             NotNullViolation.new(message)
           when ER_LOCK_DEADLOCK
             Deadlocked.new(message)
           when ER_LOCK_WAIT_TIMEOUT
             LockWaitTimeout.new(message)
           when ER_QUERY_TIMEOUT
             StatementTimeout.new(message)
           when ER_QUERY_INTERRUPTED
             QueryCanceled.new(message)
           else
             super
           end
         end

つっつきボイス:「エラーを追加したようです」「MySQL 8.0.13で追加されたエラーコードER_NO_REFERENCED_ROWER_ROW_IS_REFERENCEDに対応したんですね☺️」

「そういえばMySQLでテーブル継承ってできたっけか…?🤔ぽすぐれは昔からテーブル継承できるけど↓」

参考: PostgreSQL 10.4文書 — 5.9. 継承

「ぐぐると単一継承テーブル(STI: Single Table Inheritance)が出てきて探しにくい…😢」「STIはRailsにある機能で、今言ってるテーブル継承はDBMSの機能の話だから別なんですけどね☺️」「とりあえずMySQLのは見当たらないですね」

参考: Active Record の関連付け (アソシエーション) | Rails ガイド — ※近々ガイドの「シングルテーブル継承」を「単一テーブル継承」に統一しようと思います🙇
参考: 単一テーブル継承 - Wikipedia

CSP周りのバグ修正

# actionpack/lib/action_dispatch/http/content_security_policy.rb#L16
       def call(env)
         request = ActionDispatch::Request.new env
         _, headers, _ = response = @app.call(env)

         return response unless html_response?(headers)
         return response if policy_present?(headers)
         if policy = request.content_security_policy
          nonce = request.content_security_policy_nonce
-         headers[header_name(request)] = policy.build(request.controller_instance, nonce)
+         context = request.controller_instance || request
+         headers[header_name(request)] = policy.build(context, nonce)
        end
         response
      end
# actionpack/lib/action_dispatch/http/content_security_policy.rb#L251
       def resolve_source(source, context)
         case source
         when String
           source
         when Symbol
           source.to_s
         when Proc
          if context.nil?
            raise RuntimeError, "Missing context for the dynamic content security policy source: #{source.inspect}"
          else
-           context.instance_exec(&source)
+           resolved = context.instance_exec(&source)
+           resolved.is_a?(Symbol) ? apply_mapping(resolved) : resolved
          end
        else
          raise RuntimeError, "Unexpected content security policy source: #{source.inspect}"
         end
      end

つっつきボイス:「pixeltrix先生の修正です」「なるほど、W3CのCSP仕様だと'self'と引用符で囲むようになってる↓のでその書式に合わせたということか🤓」「ほんとだ😳」「バグだけど、もしかするとブラウザによっては引用符なしでも許しちゃってるのがあるのかも?」

Content-Security-Policy: default-src self    # 仕様違反
Content-Security-Policy: default-src `self`  # OK

参考: Content Security Policy Level 2 — default-src usage
参考: コンテンツセキュリティポリシー (CSP) - HTTP | MDN

read/write_attributeの文字列アロケーションを削減

先週のウォッチ#34270も文字列アロケーション削減でしたね。

# activerecord/lib/active_record/attribute_methods/read.rb#L31
      def read_attribute(attr_name, &block)
-       name = if self.class.attribute_alias?(attr_name)
-         self.class.attribute_alias(attr_name).to_s
-       else
-         attr_name.to_s
+       name = attr_name.to_s
+       if self.class.attribute_alias?(name)
+         name = self.class.attribute_alias(name)
        end
         primary_key = self.class.primary_key
         name = primary_key if name == "id" && primary_key
         sync_with_transaction_state if name == primary_key
         _read_attribute(name, &block)
      end

つっつきボイス:「PRにもあるように、name = attr_name.to_sで前もってシンボルを文字列に変換することで、その後のattribute_alias?で無用な変換を避けてアロケーションを減らしたということか」

up front: 前金、前払い、あらかじめ

ドキュメントに記述を追加(2件)

# activesupport/lib/active_support/callbacks.rb#L26
+ # By default callbacks are halted by throwing +:abort+.
+ # See +ClassMethods.define_callbacks+ for details.
+ #

つっつきボイス:「:abortでコールバックを止められるという記述がAPIドキュメントに追加されました」「詳しくはソースを読んでくれと↓😆」

The default terminator halts the chain when a callback throws :abort.
api.rubyonrails.orgより

参考: ActiveSupport::Callbacks::ClassMethods.define_callbacks

「Railsにabortがあるのかなと思ったら、これはRubyのKernel.abortなんでしょうね」

;追記2018/10/30: 以下のご指摘をいただきました。ありがとうございます!

参考: 終了処理 (Ruby 2.5.0)

# guides/source/action_mailer_basics.md#L842
-Intercepting Emails
+Intercepting and Observing Emails
-------------------
- There are situations where you need to edit an email before it's
-delivered. Fortunately Action Mailer provides hooks to intercept every
-email. You can register an interceptor to make modifications to mail messages
-right before they are handed to the delivery agents.
++Action Mailer provides hooks into the Mail observer and interceptor methods. +These allow you to register classes that are called during the mail delivery life cycle of every email sent.
+ ### Intercepting Emails
+ Interceptors allow you to make modifications to emails before they are handed off to the delivery agents. An interceptor class must implement the `:delivering_email(message)` method which will be called before the email is sent.

つっつきボイス:「ObserverのドキュメントがAction Mailerのガイドに追加されたそうです」「あー、受信のObserverね😃一時期探したことあるんですけど、確かにAction Mailerには前からそういう機能(register_observer)があって、いわゆる受信メールルックを行う」「Observerはデザパタなんですね」「そんな大層なものでもなくて、Observerに登録しておけばメール受け取ったときに動くよというヤツです😎」

参考: ActionMailer::Base.register_observer

# 同PRより
class EmailDeliveryObserver
  def self.delivered_email(message)
    EmailDelivery.log(message)
  end
end

参考: ActionMailer の送信ログをとりたい - Qiita — Observer
参考: Observer パターン - Wikipedia

[保存版]人間が読んで理解できるデザインパターン解説#3: 振舞い系(翻訳)

「メール受信をフックして何かを起動するという処理は昔よく行われてて、たとえば外部向けのAPI呼び出し機能はないけどメールだけは受信できるなんていう古〜いシステムでは、特定のメールを受け取ると機能をトリガするものがありましたよ」「へ〜!😳」「今も覚えているのは、APIなんかないAS/400(IBMの代表的なミニコン)のシステムとデータ連携するときにCSVファイルをメール添付で渡すようになってたこと」「おほAS/400😆」

参考: System i - Wikipedia — AS/400の後継だそうです。

Rails

特集「肥大化したActiveRecordモデルをリファクタリングする7つの方法」今ならどうなる?

肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)

「上はTechRachoで長年ずっと参照いただいてる定番記事ですが、以下のブクマ↓が気になったのでもう少し現代的な内容で別記事にできないかなと思って(できるんだろうか😓): 大ネタなんで次回の公開つっつき会にも持ち込もうかと考えてます」「確かにこれ相当昔の記事ですよね☺️」「Code Climateさんの元記事は2012年ですし👵」

肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)

だいぶ古い記事、Service Objectは今で言うUse Caseと同じパターンと言えそう

2018/01/06 03:08

その1: 設計パターン名の呼び方はまちまち

「そもそもこういう設計のパターン名って言語やらフレームワークやら時代やらで相当ばらついてますけどね😎」「村ごとにというか山を越えるともう呼び名が違うみたいな😆妖怪ですか」「GoF以外のパターン名がありすぎ😆」

「でも記事の内容の一部は古くなってるのは感じますね」「以前のウォッチでも『Form Objectの役割のひとつはform_withのおかげで消えたかも』という話題もありましたし」

「時とともにパターンの名前やあり方が変わっているものもあるし: たとえば記事中のPolicy Objectなんてのは今や自分でこしらえるよりはPunditとかCanCanCanあたりをポリシーとして使う方向になってるし☺️」「それもそうか」

「あとDecoratorとかPresenterってのも最近あまり聞かないな〜🤔」「そういえば」「元々キライだけど😆」「Decoratorって割と揉めやすい印象ですね: Presenterという呼び名がよくないなんて言われたり」「というよりDecoratorはトゥーマッチなことが多くて🧐」

Form Objectはキライな人もいるみたいだけど、明らかにビューとコントローラで使いやすいので自分はあっていいと思うし死んでもいないと思う: それをForm Objectと呼ぶかActive Modelと呼ぶかというのはあるにしても」

Query Objectも今も普通にあるよねって思うし」

View Objectみたいなのは自分は書かないな〜☺️」

「この辺は内容よりも呼び名の問題という気もするし、記事自体の主観が強い気もするし(自分にはトゥーマッチと思えるパターンもあったりするし)」「もう少ししたら他の社員もつっつきに来ると思うのでまたつっつきましょう😋」

その2: 案件ごとに設計用語を揃えたい

「ちーっす」「Service Objectパターンが一部で『Use Case』って呼ばれてるんだそうです」「Use Case?🤔それは知らんかったな〜」「そう呼んでいる村はある😆」「気持ちはわかる: ServiceというよりUse Caseの方がそれっぽいと言えばそれっぽいかも?」「Martin先生は同じものを『Application Service』と呼んでる🕶」

参考: Design and Coding Applications for Performance and Scalability in WebSphere — p35にApplication Serviceが説明されています

「結局人によって呼び方が全然違っているという🤣」「統一はされてない🤣」「ということは、GoF以外のデザインパターンや設計パターンは『誰の』『何というパターン』まで指定しないと確定できないってことになる🤣」「さすがにGoFのデザインパターンにオレオレの名前をかぶせてくるヤツはいないだろうし😆」「いないいない😆」「自分がつらくなるだけだし😆」「GoF以外だと名前どんどんかぶせられるけどなっ」

参考: デザインパターン (ソフトウェア) - Wikipedia
参考: ギャング・オブ・フォー (情報工学) - Wikipedia — GoFと略されます

「まぁデザインやアーキのパターンって世の中にいっぱいありますし」「何しろデザインのパターンですから☺️」「上の『肥大化したActiveRecordモデル…』に出てくるパターンはRails村ではコンセンサスと言っていいんでしょうか?🤔」「たぶんそんなことはない😆: この記事を書いた人が使ってるパターン名だと思うし」「Railsでは流通してるとも言い切れないし☺️」

「ただこういうパターンは名前からだいたいどういうものを指すのかは見当がつくといえばつくから、それで持っているところはあるかも🤓」「それはありますね😋」

「それで言うとForm Objectには名前や意味のぶれはあまりないと思う」「まあフォームが入れ子になってるとか、やけに高機能なForm Objectはあったりしますけどね〜😆」「それでもHTMLの1つのフォームに1つのForm Objectが対応するという点では変わらないし」「確かに〜」

「一方Value ObjectService Objectは名前や意味がぶれまくり😆」「そういえば昼間タバコ吸いながら『Service Objectって言わずにCallableって言えばいいのに』って話になりましたね」「そうそう🤣また一個できたし」「callするだけだからCallableはそれなりに納得」「ところがService ObjectをApplication Facadeだと考える人たちはきっと『違う!』って言うんですよ😆」「そうなりそう😆」

参考: Application Facades — martinfowler.com

「なお自分は(Martin先生の言う)Application Facadeの方がどっちかというとService Objectに近いと思ってます😋」「確かに設計の上位レイヤから降りてくるものだとFacadeになるんですけど、局所的な実装はcallだからCallableでよくね?って思ったり」「ってな具合に文脈がズレると話が噛み合わなくなったりするという」「それぞれのパターンでやりたいことはわかるんだけど、サンプルコードが出てきた途端に『これ違うんじゃ?』という気持ちが湧き起こったり😆」

Query Objectも、他の言い方はあまりないかなという気はするけどどうだろう?」「ふーむ🤔」「記事の中ではForm ObjectQuery Objectは割とぶれない方かな」

View ObjectPolicy Objectは村によってかなり意味合いが違っていそうではある」「それあるかも」「下手をすると村ごとにまるで意味が違っていそう😆: Policyがビジネスロジックのポリシーなのか、フレームワークレベルのポリシーなのかとか」「Viewもどのビューかとかね😆」「殴り合いの原因になりがちな筆頭はだいたいView ObjectとPolicy Objectという印象💣」

「やっぱり会社とかチームでは設計用語を合わせないといかんなという気持ちになってきますね:『このプロジェクトではGoFとMartin先生の設計用語を使います』みたいに決めとかないとそのうち殴り合いが🤣」「🤣」「それマジで必要な気がします」「殴り合いが始まったら決めないといかんかも😆」

「その意味ではプロジェクトでrails newして最初にREADMEを書くときに設計用語についても決めて書いておくべきかもですね」「READMEに書いておけば誤読しないで済むし」「確かに〜」「rails newした直後にそんな意識高いこと書けっかな〜自分😆」「設計用語の決めごとのテンプレート作ってそのURLを貼るとかするといいかも😋」

その3: Railsのディレクトリ構成をどうにかしたい

※この日のつっつきはここが最後でした。

「ちーっす」「上の『肥大化したActiveRecordモデル…』が古いんじゃないかっていう話してました」「☺️」

「そうそう、当時のこの記事でapp/の下にディレクトリを全部並べる↓のってどう考えてもやりすぎだろって思ってた😆」「これ当時の私が全然わかってなくてサンプル用にもらったスクショをそのまま載せてしまって何度かツッコまれました😅」「こんな究極のトゥーマッチアプリが本当にあったら、マイクロサービスとまでいかなくても分離すべきっしょ😆」「この図今度削除しときます🙇」

「ところがこういうディレクトリって最初にえいやっと作っておかないといつまで経っても作られないのよね😓」「それもそうなんですよね😆」

「少なくともmodels/ディレクトリの下がカオスになるくらいだったら、モデルの役割を分担するためのディレクトリを早めに作っておくべきと思うし」「そう思うしっ😄」

「理想を言えばだけど、ActiveRecordのものを入れるディレクトリとActiveRecord以外のものを入れるディレクトリは別にしたい!」「それ昼にタバコ吸いながら同じ話が出ました☺️」「そう強く思うしっ😄」

「もっと言うと、たとえばactive_records/みたいな複数形のディレクトリがあればよかったのにっ😆」「ActiveRecordを継承するものを置くディレクトリと、概念モデルとかApplication Object的なものを置くディレクトリは分けたいっっ」「ほんに: ActiveRecordは永続化層ですし」「分けたいっっ」「もう常に分けたいと願っているし🙏」

「その置き場所はきっとlib/じゃなさそうですね」「lib/じゃな〜い😆」「じゃな〜い: 置きたいのはライブラリじゃなくてApplication Objectだから」「そのアプリケーションにしかない固有のものだから☺️」

「気持ち的には、ActiveRecordがらみのものを置くディレクトリには別の新たな名前をつけたい: だって本来モデルはモデルであって永続化層じゃないんだから、本当ならmodels/にはActiveRecordじゃないものを置きたいし」

参考: ドメインモデル - Wikipedia

「ところがそうしたとすると、今度は『じゃActiveRecordのクラスを置くディレクトリは何て名前にするの?』ということになって考え込んでしまうという😆」「正直、いい名前が全然思いつかないっ😅」

「自分もいろいろそういうのを考えた時期があって、たとえばmodels/の下で名前空間を切ってそこに閉じ込めるべきか、とか😆」「でも、追加のディレクトリはmodels/とかと同じ階層に並列させる方が気持ちとしても収まりがつくし、結局追いやすいという」「モデルと違うものは違うディレクトリに置いてくれって思うし😆」

「その流れで言うと、kazzさんが作ったクラス(この後を参照)がActive Modelに置かれているのは、Form Objectのところに置くべきかなと思うわけですよ🤣」「ま、ま、そこは自分も悩ましくて、外から見たときにそれが永続化層なのかビジネスロジックなのかあいまいという点については自分は許せる、でもそのクラスの中にビュー的なものは入れたくないという気持ちがあってですね〜😅」「それもわかる☺️」「本当ならそれも切り分けたいところなのに😭」

「ヘキサゴナルアーキテクチャじゃないけど、こうやって置き場所を考えているとレイヤが違うだろという疑問は常に付いて回る」「そう思うっ😢」「そう考えるとRailsのapp/の下のディレクトリ構成ってもう限界なんだと思うし」「同意っ😤」「app/の下についてそのあたりをもう少し自由にやれればいいのにって思ったりするし」

参考: ヘキサゴナルアーキテクチャ(Hexagonal architecture翻訳) | blog.tai2.net

「たとえばヘキサゴナルアーキテクチャの層的に、外側のサービス層と内側のモデル層は一回どこかでサブディレクトリ化してもいいのでは?って思うことあるし」「そうそうっ😤」「そうなれば、プログラミングに慣れてない人でも『こういうことか』と納得してくれて、変なところに変なクラスを置いたりしなくなる効果があるんじゃないかって思うわけですよ」「同意同意っ😤」「そして一見似ているけどレイヤが違うものも、きっとちゃんと分けてもらえると思いたい☺️」

「そもそもapp/の下にassets/があるのっておかしいし🤣」「🤣」「たしかに〜」「assets/はむしろpublic/の方が近い」「assets/ってコントローラやビューやモデルと並列されるものじゃないし😅」「実に不思議」「ヘルパーまで並列に置いてあるし😭」

「シンプルなアプリだったら今のRailsのディレクトリ編成でも別にいいんですけど、アプリがでかくなってきたときにそういうところが苦しくなってくる」「ディレクトリを動かそうと思えば動かせるのに現実には動かす時間が取れないという😅」

「ちょっと思ったんですけど、どうせならComplexRailsみたいな拡張に耐えられるバージョンをこしらえて欲しいっっ🤣」「🤣」「新幹線だって線路の軌道広くしてるんだからRailsだって外側にもう一本線路を敷いて欲しいっっ🚅」「わかる〜🤣」「🤣」「このアプリはローカル線、このアプリは成長したから広軌にお引越しね、みたいな: rails newで新幹線モードみたいなオプション付けたらディレクトリ構造ががらっと変わるとか」「expressモードというかcomplexモードというか」「DHHなら『それRailsで作るのやめろ』とか言いそうですけど🤣」

参考: 広軌 - Wikipedia

「ってなことをさっきの肥大化記事を読みながら思ったわけですよ😆: 5年前に読んだときはトゥーマッチかなって思ったけど、今見ると結構必要なものがあるなって思えてきたし」「個別のパターンやディレクトリの良し悪しじゃなくて、必要なものはこの中に確かにあるー」「今のRailsのデフォルトのディレクトリ編成も、アプリが複雑になったときにスムーズに対応しやすくする方法があるんじゃないかという気がしてくるんですよね🧐」「ありそう!ありそうなんだけどそれが中々見えない😢」

「だからTrailbrazerが出てきたんですね」「そういう意味でTrailbrazerは結構いい😍: 巨大なアプリになるとわかれば一度使ってみたいと思うし」「ただね〜、最初に軽いものを作るときはトゥーマッチなんですよね😅」「ほんとそこが悩ましい😩: プロトタイプで作ったアプリがそのまま本番行きで拡張されまくったり」「シンプルとコンプレックスの間にギャップがあるのが問題」

「オーバーキル覚悟で一度Trailbrazerに挑戦するしかないのかな…」「ただその一方で、今のシンプルなRailsで十分足りる人もいっぱいいるわけですよ: ここで今したような話も、最先端というよりは真ん中やや遅れ気味ぐらいのところかなとも思うし」


trailblazer.toより

「このお話、次回の公開つっつきに持ち込みたいと思います: お疲れさまでした〜」

ものも言わずにコケるWebpackerのデバッグ(RubyFlowより)


つっつきボイス:「Webpackerはいくらでもサイレントリーに死にそうではある😇」「実は今自分のオレオレRailsアプリをWebpackerベースでrails newして作り直そうとごそごそやっているんですが、やっているうちにだんだんWebpackerに変える意義がよくわからなくなってきてて💦」「まあアセットの作り方が変わっただけといえばそれまでで、Webpackerで何か新しいことができるわけでもないし手間は増えるし🤣」「🤣」

「新オレオレアプリではWebpackerを入れる代わりにSprocketsとTurbolinksを殺してみたんですが、よかったのかな…?🤔」「そこは確かに悩ましくて、Sprocketsはフロントエンジニアと連携するときに邪魔になるので殺したいというのはわかる」「そしてそれ以前にWebpackとSprocketsを両方使うと死にそうになるんで、どっちかを殺すとなったらSprocketsを殺すという感じですかね〜」「なるほど!😃」「アセットパイプラインでWebpackとSprocketsを両方使うぐらいならWebpackに寄せるだろうな、と自分は理解してます☺️」

参考: アセットパイプライン | Rails ガイド — Sprocketsの解説
参考: Rails で JavaScript を使用する | Rails ガイド — Turbolinksの解説

「Railsが遅い」とボヤく前に


つっつきボイス:「原文タイトルは煽りまくりですが内容は割と普通で、上の日本語タイトルで補完してあります😆: Railsアプリが遅いならまずSQLクエリとか設定とかを疑えという感じの内容でした」「自分も『Railsって遅いんでしょ?』って言われたらそう説明すること多いな😎: Rails自身の速度がそこまでクリティカルに影響するような凄いアプリってそうそうあるものでもないですし😆」

PayPalで使われているGraphQL


つっつきボイス:「PayPalもGraphQL使うようになったのか、へぇ〜」「BPSではもっぱらアレ使ってますよね(何だっけ)」「Stripe↓」「そうでした」

Stripe決済を自社サービスに導入してわかった5つの利点と2つの惜しい点

「PayPalそのものはともかく、古いAPIがずっと生き延びているのと、古いAPIで作ったオブジェクトを新しいAPIで参照できないなど新旧APIで設計上の互換性がないところがつらい😩」「あー」「あとドキュメントもあんまりイケてない: 新旧サービスがあるからドキュメントも新旧あるのは当然なんですが、新旧で同じようなサービス名や同じようなAPI名がたくさん出てきてわからなくなったり😢」「そうでしたか…」「おそらくですが命名方針がビジネスに寄り過ぎてて統一性が後回しになってるんじゃないかな」

「ところでPayPalに限らないけど決済サービスでGraphQLを使う意義ってどのぐらいあるんだろうか?🤔決済でそんなに複雑なクエリが欲しくなるとも思いにくいし、あるとすればPayPal側で集計処理させてその結果をいろんな形で取り出したいときとかかな?」「それもそうかも」

Railsのバリデーションとマルチページのフォーム(Hacklinesより)


つっつきボイス:「最近kazzさんがフォームで複数のモデルを扱おうとして苦心しているので」「kazzさんは今作っているクラスをActive Modelと呼んでるけど自分はそれをForm Objectと呼んでますね(コードはどっちでもまったく同じですが😎)」「置き場所が違うだけなんですね😃」「結局そういうものを作るのが一番近道だし後々メンテしやすいし」

「この記事はマルチページフォームの話だけど、確かにマルチページフォームはつらい!😖」「Windowsインストーラのウィザードみたいに複数ページにまたがるフォームですね」「あ〜validatesif:を書く↓のはヤバい👻」

# 同記事より
Class Person < ActiveRecord::ApplicationRecord
  validates :name, presence: true
  validates :date_of_birth, presence: true, if: create_stage > 1
  validates :ni_number, presence: true, if: create_stage > 2
end

「モデルのvalidatesif:を書くくらいだったらForm Object的なクラスに切り出すべき: そうしないとあっという間につらくなるし、それに限らずActiveRecordを継承しているところでvalidatesに条件を付けるとだいたい後で酷い目に遭う🎃」「副作用がひどそうですね…😓」「フォーム側で必要なバリデーションが永続化データのバリデーションの中に入ってくるともうそれだけで混乱するし、DBで永続化されたデータが正しいのかどうかも確信できなくなる😩」

追いかけボイス:「モデルのvalidateson:使うのも要注意よ〜」

参考: Active Record バリデーション | Rails ガイド

セキュリティチェックリスト2本立て


つっつきボイス:「2つの記事はこの間公開した記事↓で参考に挙げられていました」「1本目はあまり見たことない感じですが普通にRailsのセキュリティチェックリストとしてよさそうですね」「★も1000超えてますし😊」「RailsはとりあえずBrakemanで機械的にチェックできるセキュリティホールを全部つぶしておくのが吉」

Railsアプリで実際にあった5つのセキュリティ問題と修正方法(翻訳)


presidentbeef/brakemanより

「へぇぇ、RedcarpetHTMLSafeってあるって初めて知った😁」「Redcarpetって久しぶりに見る名前だけど何だったっけ…」「Markdownが使えるようになるエンジン」「でした」「1本目のセキュリティチェックはRailsだけじゃなくてgemも対象にしてますね: Brakemanをちゃんとアップデートしろとかも書いてあるし」

# eliotsykes/rails-security-checklist
# bad
renderer = Redcarpet::Render::HTML.new

# less risky
renderer = Redcarpet::Render::Safe.new

「Detectify?」「detectify.comっていう脆弱性チェックサービスみたいです」「なるほど: こういうブラックボックステストやってくれるところはいろいろありますけどね😊」


detectify.comより

「2本目↑は文字通りCTO向けの自社セキュリティチェックリスト: RailsやWebアプリ以外にも広く使える」「SaaSでなくてもいいと」


cto-security-checklist.sqreen.ioより

Deviseのパスワードを安全に保つには


つっつきボイス:「そうそう、パスワードハッシュってこうやって$マークのところで意味が区切られるんですよ↓」「えっ知らなかった😳構造があるんだ…」「こういうのはPHPなんかでも作られますね: フレームワークの数だけこういうのがある😎」


同記事より

その他Rails

Ruby trunkより

Setではダックタイピングよりis_a?がいいのでは?

# 同issueより
require 'set'
class MySet
  include Enumerable
  def each(&block) [:my, :set].each(&block) end
  def size() to_a.size end
  def is_a?(klass) super || klass == Set end # <== Hack! 😭
end
puts Set[:set].subset?(MySet.new)

# => true

つっつきボイス:「ダックタイピングだと苦しいということみたいです」「Setとか使ったことないわ〜: ふと思ったけどRailsでSetって使われてたりするんだろうか?」「素のRailsにはさすがにないみたいです」「Setじゃないといけない状況があまり思いつかない😆」

参考: class Set (Ruby 2.5.0)
参考: 集合 - Wikipedia

よく見たら、issueを開いたのは以前のウォッチで紹介したpersistent-💎 gemの作者でした。

参考: Ivo Anjo / persistent-💎 · GitLab

Ruby

複数のコレクションをイテレートする(Hacklinesより)

# 同記事より
class Group
  include Enumerable

  def initialize(members)
    @members = members.dup
  end

  def iterate_members_alphabeticaly
    ite = @members.dup.sort
    while k = ite.shift()
      yield k
    end
  end

  def iterate_members_by_name_length
    ite = @members.dup.sort_by { |x| x.size }
    while k = ite.shift()
      yield k
    end
  end

  def each(&block)
    enum_for(:iterate_members_by_name_length).each(&block)
  end
end


group1 = Group.new(["Nick", "Petros", "Ana"])

group1.each {|x| p x }

つっつきボイス:「何か変わったことしてるのかな?と思って」「イテレーターをこんなふうに返すみたいな普通の話かなー🤔」「お、#enum_forなんてメソッドがあるし: enumを取ってくるメソッド↓」

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

Enumerator.new(self, method, *args) を返します。
ブロックを指定した場合は Enumerator#sizeがブロックの評価結果を返します。ブロックパラメータは引数argsです。

「enumを取ってきてeachすればそりゃ確かに動く😆」

Fir: fish風の派手目なRuby REPL


dnasseri/firより


つっつきボイス:「fish使ってないしな〜」「一瞬使ってみたけどbashに戻したことあります😅」「Firは試しに動かしてみたけどところどころつっかえるかな…終了もexitじゃなくてCtrl-Dだったし」「ま、お好きな人はどぞ〜☺️」

参考: fish shell


fishshell.comより

Ruby内部の動きを探ってみる


同記事より


つっつきボイス:「まさにRuby内部の動きを追っているし↑パースしてASTを切ってみたいな」「『Ruby Under Microscope』的なところですね: 私はGobyでこのあたりを学びました😅」「これはいい記事っぽい😍」

参考: 書籍紹介『Rubyのしくみ Ruby Under a Microscope』

記事のタイトルはこちら↓のもじりのようです。

参考: 計算機プログラムの構造と解釈 - Wikipedia
参考: SICP Web Site for the Japanese Edition — 第二版の日本語訳が全文公開されています。

強力な暗号化鍵(Hacklinesより)

# 同記事より
SecureRandom.random_bytes(32)

つっつきボイス:「Rubyで安全な乱数はSecureRandom↓から取るというのはもう基本ですね」「randを暗号化とかに使ったらあかんと」「randはセキュアでないのでよろしくない🧐」

参考: module SecureRandom (Ruby 2.5.0)
参考: module function Kernel.#rand (Ruby 2.5.0) — 「疑似乱数」なので
参考: 擬似乱数 - Wikipedia
参考: Rubyで乱数生成 - 或るプログラマの開発日記

SecureRandomにはhexってのがありますね」「あ、昔それ踏んで直してもらっちゃったことあったな〜💦」

require 'securerandom'
p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"

「もっとちゃんとしたdigestを取りたかったらOpenSSL::Digest↓(重いけど😅)を使うとか、いろいろやり方はありますね」

参考: class OpenSSL::Digest (Ruby 2.5.0)

「お、記事にあったrbnacl↓っていうgemの方が面白そう😃: ★も700超えてる」「Railsでも使えると書いてる」「ライブラリが今後メンテされるかどうかがちょっとコワイ🎃: こういうコアライブラリは基本的にメジャーなものを使うべきだと思いますね🤓」


同リポジトリより

「READMEに書いてあったGPG↓、一瞬PGPに見えちゃった😅」「GPGはものすごく歴史古いですね📃」

参考: GNU Privacy Guard - Wikipedia

Yabeda: Rubyアプリのinstrumentation gem(Hacklinesより)


同リポジトリより

TechRacho記事でおなじみのEvilmartiansのブログです。

Rails+PostgreSQLのパーティショニングを制覇する(翻訳)


つっつきボイス:「ebay向けに作ったgemみたいです」「やべだ?」「Prometheusをこれだけ密にインテグレーションできるとしたらなかなかいいかも?」


prometheus.ioより

RailsのパフォーマンスをPrometheusで測定する(翻訳)

「ははぁ、Yabedaを使ってまとめてPrometheusとかに投げられる↓ってことか: よさそう😍」

「yabeda-muninとかないのかな😆: そしたらBPSで使える」「まぁmuninのアダプタはたぶん超楽勝で書けそう🤓: コマンド実行したら値を返すスクリプトを書けばそれでおしまいなので」「muninってそんなにシンプルなんだ!」「シェルスクリプトでも書けるぐらいなので😉」

参考: Munin


munin-monitoring.orgより

参考: サーバー監視ツール Munin - Qiita

その他Ruby


つっつきボイス:「2本のうち1本はRubyでスクレイピングする記事ですが、こういうのはいっぱいありそうですね」「スクレイピング情報はいっぱいあるけど、本当にちゃんと書かれているのは意外に少ないですね」「そっかも」「スクレイピングは結構ノウハウが必要なんですよ: お、この動画は不定形なデータのスクレイピングも解説しているようだ」

クラウド/コンテナ/インフラ/Linux/Serverless

AWS Auroraがプライムデー初日にコケた

参考: Amazonプライムデー初日にサーバーがダウンしたのは「DBをOracleから自社製に乗り換えた」ことが最大の理由 - GIGAZINE


つっつきボイス:「そうそうこれね☺️」「記事を読み進めないとAuroraだということがわからなかった💦」「むしろ今までAmazonがまだOracleだったんだという勢い😆」「とは言え、AWSほどの規模でAuroraに乗り換えたのはさすがだなと思いますね💪」「おそらくAWSでもまだOracleは使っていそう」


その後続報が出ました↓。

参考: Amazonプライムデーのサーバ障害、AmazonがOracleからAurora DBに乗り換えたのが原因ではない。Amazon CTOがCNBCの報道を否定 - Publickey

TerraformやVaultなどがアップデート


つっつきボイス:「HashiCorpのVaultって何でしたっけ?」「名前だけ見て言うとセキュリティとか認証がらみでしょうね」「いわゆるKMS的な機密情報を管理する」

vault: 金庫室、地下納骨所、墓地

参考: Key management - Wikipedia


vaultproject.ioより

「HashiCorpは結構頑張ってますね: マイクロサービスを自社で建てるみたいなことをやってる会社はHashiCorpの製品のお世話になってることが多いと思う」「おー😃」

その他クラウド


つっつきボイス:「ライナスがきれいなライナスになったか😆」「寺に籠もって反省したんでしたっけ」「Richard Stallman御大がコメントを寄せてたのにはつい笑った😆」「えっ知らなかった😳」

後で探してみたところ、この辺かなと思いました↓。

参考: Richard Stallman Says Linux Code Contributions Can’t Be Rescinded - Slashdot
参考: Richard M. Stallman on the Linux CoC : linux

参考: リチャード・ストールマン - Wikipedia

Stallmanと言うと彼の自作の歌を思い出してしまいます↓。


終わっちゃいましたが。

SQL

大物リリース2本立て(DB Weeklyより)


つっつきボイス:「先週PostgreSQL 11が出たのはウォッチでも簡単に書きましたが」「ぽすぐれも年1でがんがんリリースするポリシーに変えたのかな?」「昨年10月にPostgreSQL 10をリリースしてちょうど1年ですしね」「PostgreSQLはメジャーアップデートで機能を増やすというポリシーでこれまでやってきてたはず」

「そしてその後でRedis 5も出たそうです」「Redisを自分でアップグレードするとかあまり考えたことなかったナ😁」「とりあえずredisでStreamができるようになった↓というのが目を引きました」「redisは何でもできるから😋」


redis.ioより

参考: Introduction to Redis Streams – Redis

「ほー、Streamってこういうことか↓」「というと?」「ものすごく大量のデータを時系列でぶちこんでいくデータストリーム的なものをここではStreamと呼んでますね: いわゆるDSMSと呼ばれるヤツ」「おー」

# redis.ioより
> XADD mystream * sensor-id 1234 temperature 19.8
1518951480106-0

参考: データストリーム: 用語解説辞典|【公式】NTTPC
参考: データストリーム管理システム(DSMS) - Wikipedia

「PostgreSQLだとウィンドウ関数↓でたとえば『直近10万件のデータを保持取得する』 などのストリーム処理ができますが、redisでもそういうことができるようになったんでしょうね☺️」「データが追加されると古い方から消えていくとか、あるいはそのシステムにクエリを置いておくとデータを取り出せるみたいなことに使ったりします🧐」「redisすげー😳」「ここまでくるとストリーム管理システムと言っていいでしょうね: ちゃんと見てないけど、これができるということはContinuous Queryとかも投げられるんだと思う」

参考: PostgreSQL 10.4文書: 3.5. ウィンドウ関数
参考: InfluxDBのContinuous Query その1 | Yakst

ストリームシステムのクエリ

「ちなみにストリームシステムのクエリは、SQLとかのクエリとやや概念が違います」「おぉ?」「SQLとかだとクエリを投げたらトランザクショナルに処理されて必ず返ってくる」「ストリームシステムの場合、クエリを投げるんじゃなくて前もってストリームシステムに置いておく: たとえば『直近10件の移動平均を求めるクエリ』なんてのを置いておくわけです」「むむ?」「これがContinuous Queryという考え方で、その後でデータがストリームとしてやってくると、配置したクエリがそれに応じて結果をストリームで返す」「なるほどー!😃」

「このシステムはストリームを扱うので、ストリームの処理結果をストリームで返すところがポイント」「だからContinuousか〜😋」「ってなことを学部生時代に研究でやってました🤓」

「そしてPostgreSQLは同じようなことをウィンドウ関数でDBMSでやれる😎」「そういうことかー」「redisのStreamはざざっと見た感じではクエリの書き方がぽすぐれのに近そうな印象: 型のあるデータストリームっぽいし」

「そしてこういうストリーム処理をニューラルネットワークっぽく相互接続するのがAWS Kinesis↓とかApacheのHadoop↓とかですね」「なるほどなるほど!🤩」「KinesisやHadoopは、単なるレコード単位の処理ではない、もっと有機的なストリーム接続を扱うので、MapReduceとか使ったりとかまた少し違いますが🤓」「何だかすげ〜🤖」「やっぱredisは何でもできるなっと😋」

参考: Amazon Kinesis (フルマネージド型リアルタイム大規模ストリーミング処理) | AWS
参考: Apache Hadoop


hadoop.apache.orgより

JavaScript

V8のソート(JavaScript Weeklyより)

記事中の「Timsort」が気になってググると、過去にJSでTimsortがバグったという記事がわらわら出てきました。

参考: Timsort - Wikipedia


つっつきボイス:「Timsortっていう言葉が気になって」「prototypeチェインとかいろいろ頑張ってる感」


同記事より

「あとV8内部で使われているというTorqueというDSLも気になりました: V8が自動車のエンジンだからそれになぞらえたっぽい名前」「やっぱりこういうマルチプラットフォームで動作する言語系ではこういう中間言語的なものがあると便利なんでしょうね😋: LLVMやJavaもまさにそうだし」「そうそうJavaのJVMとか」


同記事より

参考: Torque user manual · V8
参考: 中間言語 - Wikipedia
参考: LLVM - Wikipedia
参考: Java仮想マシン - Wikipedia

ちょうどV8 Torqueの日本語スライドも見つけました↓。

ES6ではコレクションを扱える

「それでちょっと思い出したけど、今大学の授業で使うスライドのためにES6を調べながらJavaScriptのArray.forEach()↓の説明を書いてるところですよ☺️」「ES6だとそうやってRubyみたいに書ける!?」「そう、ついにJavaScriptでコレクションを触れるようになる😂: もうこれで何でもできるぜって教えられるし💪」

参考: Array.prototype.forEach() - JavaScript | MDN

// developer.mozilla.orgより
let array1 = ['a', 'b', 'c'];

array1.forEach(function(element) {
  console.log(element);
});

// expected output: "a"
// expected output: "b"
// expected output: "c"

CSS/HTML/フロントエンド/テスト

絵で見るWebAssemblyのポストMVP機能(Frontend Focusより)


同記事より


つっつきボイス:「MVCかと思ったらMVPでした💦」「Minimum Viable Productだよね?」「ですです」

参考: Model View Controller - Wikipedia
参考: MVP(Minimum Viable Product)とは | リーン・スタートアップの基本とMVPの実践 - その他ビジネス | ボクシルマガジン

「図が豊富なのはいいんですけど、英語圏はこのぐらい↓でもカートゥーンって呼ぶんだなと思って😆」「ポンチ絵的な😆」「まあポンチ絵よりはカートゥーンの方がまだ人様の前では格好がつくかも🤣」

同記事より

「そういえばポンチ絵って明治時代の新聞だか雑誌のタイトルから来てたのを思い出しました」「(ググって)《ジャパン・パンチ》ね」「それそれ」「浮世絵!そんな時代とは🤣」

参考: ポンチ絵 - Wikipedia
参考: 《ジャパン・パンチ》(じゃぱんぱんち)とは - コトバンク

「ソフトウェアメトリックス」2018版

日本情報システム・ユーザー協会というところが作成しているらしい。元経済産業省所管らしいので怪しいところではないようだ。
気になったのは
* 仕様変更の発生とプロジェクト全体満足度の割合で「変更なし」73%,「軽微な変更が発生」76%に上がっていたこと
* 「概要レベルのCRUD図」「業務構成表」「概要レベルのER図」「ビジネスプロセス関連図」は三分の一以上が作成していない。
* 受入テストやユーザー総合テストでの設定項目は「業務シナリオ」「要件確認」が多い。
* 保守容易性確保のガイドラインの有無
気になったというかそうなんだなーと思った程度


つっつきボイス:「社内Slackのtest板からいただきました🙇」「一般社団法人!」「テスティングやってる人ならこの辺は既に常識なのかなと思うけど、外からだとなかなかわからないよね😆」「しかも日本ドメスティックだし😆」「まあたとえばISCなんかも業界の外の人は普通知らないでしょうし☺️」「ともあれ、テスティングを体系的に行う方法はソフトウェア工学としてはちゃんと存在しているので」

参考: Internet Systems Consortium - Wikipedia


isc.orgより

「こういうグローバルな調査はもちろん大事だけど、母集団がどれぐらい偏ってるか恣意的な要素が混じってないかとかが気になるところだし😆自分たちの開発における意義としては、たとえばCIのエラー件数の推移を取るとか、コード量の増加に対してカバレッジがどう増えているかとかの方が恣意的な要素が入りづらいし実用的かなという気はしますね: Railsならrake statsとかで取れるし」「そうかも☺️」

参考: rails アプリの統計情報を一発で取れる rake stats を試した - yagihiro output

その他HTML


つっつきボイス:「お、PinPをWeb APIで提供できるのか!どっかでこれちらっと見たな…」「へぇ〜😳」「みんな凄いこと考えるな〜: ついに動画がブラウザの外に飛び出すぞっと😆」「ホントだー飛び出してるー」「ブラウザ閉じたら動画も閉じちゃうんだろな😆」

言語よろずの間

Pythonってそんなに遅かったかしら


つっつきボイス:「日本語訳があるのでそっちで」「PythonにもGILはやっぱりあるんだなー」「インタプリタ言語だと先読みとかできないだろうし、GILを使わずにやろうとしたら人間が最初から並列実行できるコードを書かないといけなくなるでしょうね」「それはつらい😢」

参考: グローバルインタプリタロック - Wikipedia

「だいぶ前からPythonコードからCのコードを出力できた気がしますが、Rubyだと難しいのかな…?」「Rubyのオープンクラスがあると実行中に変わるから静的なコードにするのは難しいでしょうね」「うん難しいと思う」「もし仮にバイナリにできたとすると、きっとその中にはRubyインタプリタが丸ごと入ってると思う🤣」「🤣🤣」「mrubyならその方法でやれそう」

参考: Rubyのオープンクラス - DesignAssembler
参考: mruby-cli で ワンバイナリなツールを作ってみた - ねこのて

後で探してみると、PythonからCへの変換は決定版がなさそうな雰囲気でした。以下のshedskinもアーカイブされていました。

参考: Google Code Archive - Long-term storage for Google Code Project Hosting.

中国剰余定理


同記事より


つっつきボイス:「チャイニーズリメインダーセオリー、聞いたことだけある😆」「数学やってる人だったら11次方程式作れば原理的にこういうことできるってわかるヤツ😆」「できるところまではわかっても手作りは大変そう😅」「Mathematicaなら無理やりこういうのやれそう😁」「今ならWolfram Alphaでできるかも?」「ま、これは数学におけるワンライナーみたいなもんだし🤓」「たしかに〜」「フーリエ展開かマクローリン展開かテイラー展開のどれかでできそうな気はするんだけどなー」「数学科だったけど忘れたー😇」「忘れたー😇」

参考: Mathematica - Wikipedia


wolframalpha.comより

ふと、昔ちら見したジョゼフ・ニーダム「中国の科学と文明」を連想しました。

参考: 中国の剰余定理 - Wikipedia

参考: ジョゼフ・ニーダム - Wikipedia

その他

AI丸投げ開発とは

元記事のタイトルが秀逸だと思いました。それだけでした。

参考: そして誰もいなくなった - Wikipedia

スパイチップその後


つっつきボイス:「チップは置けてもどうやってデータを抜くんだろうなと気になってたけどやっぱり」「実はチップを人力で回収するとか😆」「それならわかるけど、メモリも内蔵してなさそうだしな〜謎🤔」

「まあ意表を衝いたデータの抜き方ってときどき出現しますけどね: クランプメーター(アンペア計)で配電盤にアクセスすることで隣の部屋のディスプレイ表示を電源ラインから取り出す裏技とかありましたし」「それできそう!」「電源ラインのノイズからデータを取り出すとは」「天才だよな😆」「そうやっていろんな技があったりするんで、スパイチップを一概に否定するのは難しい気はしますね🤓」

参考: クランプメーターの正しい選び方、使い方【図解】

その他のその他


つっつきボイス:「記事に出てくるものがいろいろなつかしくてつい😅」「当時は大学のコンピュータ部とかでこんな感じで凄いゲームを作ったりしてましたね☺️」

番外

いかにもじゃない方が好き


つっつきボイス:「トンガッたデザインにすると陳腐化早そうですよね」「電脳メガネって言葉が既に恥ずかしいぞっ😆」「😆」「網膜に直接投影するタイプのもあった気がする」「それ確実そうですね」「目に何か差し込むのかとおもた👁」

参考: 網膜投影型ARグラスの一般向け受注が開始 | Think IT(シンクイット)

教師データなしで動いたロボットハンド


つっつきボイス:「やってることはクールなんですが、ナレーションの英語がとってもインド訛りなのが気になって😆」「お、インドにしてはゆっくり喋ってる方かな: カンファレンスとかでこの数倍の速さで喋られると聞き取り大変😅」「教師データなしというより自分で教師データを作りながら学習してるんじゃないかな🤔」


今回は以上です。今度の公開つっつき会でお会いしましょう!😄

おたより発掘

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

週刊Railsウォッチ(20181022)Railsの名前空間地獄とrequire_dependency、PostgreSQL 11がリリース、clean-rails.orgほか

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

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

Rails公式ニュース

RubyFlow

160928_1638_XvIP4h

Hacklines

Hacklines

DB Weekly

db_weekly_banner

Frontend Focus

frontendfocus_banner_captured

JavaScript Weekly

javascriptweekly_logo_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ウォッチ

インフラ

ActiveSupport探訪シリーズ