- Ruby / Rails関連
週刊Railsウォッチ(20181029) 特集『肥大化したActiveRecordリファクタリング7つの方法』今ならどうなる?Redis 5のストリーム機能他
こんにちは、hachi8833です。遅ればせながら先週はGitHubの中の皆さまお疲れさまです。
昨日から発生していたGitHub の障害は復旧ました。多大なるご迷惑をおかけしましたこと深くお詫び申し上げます。
— GitHub Japan (@GitHubJapan) October 23, 2018
つっつきボイス:「自分はあの日たまたま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
になるパラメータを渡したときの挙動を変更したようだ」
「うん、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: こちらもご指摘をいただきました。ありがとうございます!🙇
このビッグウェーブに乗って指摘するとreferencesを使うように変えてるのはリファクタリングのためではなくカラムがbigintで定義されるようにするのが目的でintegerの範囲を超える値を保存できるようにしてRangeErrorを発生させるためです(テストコードなのでユーザーは気にするところではないですが)
— Ryuta Kamizono (@kamipo) October 30, 2018
「そういえば修正前の(*)
は引数を全部握りつぶす記法だというのをこの記事書いてて知りました↓」
⚓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_ROW
とER_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の文字列アロケーションを削減
- PR: Reduce string allocations in read/write_attribute by eugeneius · Pull Request #34270 · rails/rails
先週のウォッチの#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: 以下のご指摘をいただきました。ありがとうございます!
https://t.co/qJgg9O4YuK これは Kernel#abort ではなく Kernel#throw への引数 :abort ではないかと https://t.co/hqoJgIpAlr
— ( Φ _⊞) (@n0kada) October 29, 2018
- PR: Add observing emails to action mailer guide [ci skip] by baerjam · Pull Request #34080 · rails/rails
# 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
「メール受信をフックして何かを起動するという処理は昔よく行われてて、たとえば外部向けのAPI呼び出し機能はないけどメールだけは受信できるなんていう古〜いシステムでは、特定のメールを受け取ると機能をトリガするものがありましたよ」「へ〜!😳」「今も覚えているのは、APIなんかないAS/400(IBMの代表的なミニコン)のシステムとデータ連携するときにCSVファイルをメール添付で渡すようになってたこと」「おほAS/400😆」
参考: System i - Wikipedia -- AS/400の後継だそうです。
⚓Rails
⚓特集「肥大化したActiveRecordモデルをリファクタリングする7つの方法」今ならどうなる?
「上はTechRachoで長年ずっと参照いただいてる定番記事ですが、以下のブクマ↓が気になったのでもう少し現代的な内容で別記事にできないかなと思って(できるんだろうか😓): 大ネタなんで次回の公開つっつき会にも持ち込もうかと考えてます」「確かにこれ相当昔の記事ですよね☺️」「Code Climateさんの元記事は2012年ですし👵」
肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)
だいぶ古い記事、Service Objectは今で言うUse Caseと同じパターンと言えそう
⚓その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 ObjectやService 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 ObjectとQuery Objectは割とぶれない方かな」
「View ObjectとPolicy Objectは村によってかなり意味合いが違っていそうではある」「それあるかも」「下手をすると村ごとにまるで意味が違っていそう😆: Policyがビジネスロジックのポリシーなのか、フレームワークレベルのポリシーなのかとか」「Viewもどのビューかとかね😆」「殴り合いの原因になりがちな筆頭はだいたいView ObjectとPolicy Objectという印象💣」
「やっぱり会社とかチームでは設計用語を合わせないといかんなという気持ちになってきますね:『このプロジェクトではGoFとMartin先生の設計用語を使います』みたいに決めとかないとそのうち殴り合いが🤣」「🤣」「それマジで必要な気がします」「殴り合いが始まったら決めないといかんかも😆」
「その意味ではプロジェクトでrails new
して最初にREADMEを書くときに設計用語についても決めて書いておくべきかもですね」「READMEに書いておけば誤読しないで済むし」「確かに〜」「rails new
した直後にそんな意識高いこと書けっかな〜自分😆」「設計用語の決めごとのテンプレート作ってそのURLを貼るとかするといいかも😋」
⚓その3: Railsのディレクトリ構成をどうにかしたい
※この日のつっつきはここが最後でした。
「ちーっす」「上の『肥大化したActiveRecordモデル...』が古いんじゃないかっていう話してました」「☺️」
「そうそう、当時のこの記事でapp/
の下にディレクトリを全部並べる↓のってどう考えてもやりすぎだろって思ってた😆」「これ当時の私が全然わかってなくてサンプル用にもらったスクショをそのまま載せてしまって何度かツッコまれました😅」「こんな究極のトゥーマッチアプリが本当にあったら、マイクロサービスとまでいかなくても分離すべきっしょ😆」「この図今度削除しときます🙇」
「ところがこういうディレクトリって最初にえいやっと作っておかないといつまで経っても作られないのよね😓」「それもそうなんですよね😆」
「少なくともmodels/
ディレクトリの下がカオスになるくらいだったら、モデルの役割を分担するためのディレクトリを早めに作っておくべきと思うし」「そう思うしっ😄」
「理想を言えばだけど、ActiveRecordのものを入れるディレクトリとActiveRecord以外のものを入れるディレクトリは別にしたい!」「それ昼にタバコ吸いながら同じ話が出ました☺️」「そう強く思うしっ😄」
「もっと言うと、たとえば「ActiveRecordを継承するものを置くディレクトリと、概念モデルとかApplication Object的なものを置くディレクトリは分けたいっっ」「ほんに: ActiveRecordは永続化層ですし」「分けたいっっ」「もう常に分けたいと願っているし🙏」active_records/
みたいな複数形のディレクトリがあればよかったのにっ😆」
「その置き場所はきっとlib/
じゃなさそうですね」「lib/
じゃな〜い😆」「じゃな〜い: 置きたいのはライブラリじゃなくてApplication Objectだから」「そのアプリケーションにしかない固有のものだから☺️」
「気持ち的には、ActiveRecordがらみのものを置くディレクトリには別の新たな名前をつけたい: だって本来モデルはモデルであって永続化層じゃないんだから、本当ならmodels/
にはActiveRecordじゃないものを置きたいし」
「ところがそうしたとすると、今度は『じゃ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で十分足りる人もいっぱいいるわけですよ: ここで今したような話も、最先端というよりは真ん中やや遅れ気味ぐらいのところかなとも思うし」
「このお話、次回の公開つっつきに持ち込みたいと思います: お疲れさまでした〜」
⚓ものも言わずにコケる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↓」「そうでした」
「PayPalそのものはともかく、古いAPIがずっと生き延びているのと、古いAPIで作ったオブジェクトを新しいAPIで参照できないなど新旧APIで設計上の互換性がないところがつらい😩」「あー」「あとドキュメントもあんまりイケてない: 新旧サービスがあるからドキュメントも新旧あるのは当然なんですが、新旧で同じようなサービス名や同じようなAPI名がたくさん出てきてわからなくなったり😢」「そうでしたか...」「おそらくですが命名方針がビジネスに寄り過ぎてて統一性が後回しになってるんじゃないかな」
「ところでPayPalに限らないけど決済サービスでGraphQLを使う意義ってどのぐらいあるんだろうか?🤔決済でそんなに複雑なクエリが欲しくなるとも思いにくいし、あるとすればPayPal側で集計処理させてその結果をいろんな形で取り出したいときとかかな?」「それもそうかも」
⚓Railsのバリデーションとマルチページのフォーム(Hacklinesより)
つっつきボイス:「最近kazzさんがフォームで複数のモデルを扱おうとして苦心しているので」「kazzさんは今作っているクラスをActive Modelと呼んでるけど自分はそれをForm Objectと呼んでますね(コードはどっちでもまったく同じですが😎)」「置き場所が違うだけなんですね😃」「結局そういうものを作るのが一番近道だし後々メンテしやすいし」
「この記事はマルチページフォームの話だけど、確かにマルチページフォームはつらい!😖」「Windowsインストーラのウィザードみたいに複数ページにまたがるフォームですね」「あ〜validates
でif:
を書く↓のはヤバい👻」
# 同記事より
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
「モデルのvalidates
にif:
を書くくらいだったらForm Object的なクラスに切り出すべき: そうしないとあっという間につらくなるし、それに限らずActiveRecordを継承しているところでvalidates
に条件を付けるとだいたい後で酷い目に遭う🎃」「副作用がひどそうですね...😓」「フォーム側で必要なバリデーションが永続化データのバリデーションの中に入ってくるともうそれだけで混乱するし、DBで永続化されたデータが正しいのかどうかも確信できなくなる😩」
追いかけボイス:「モデルのvalidates
でon:
使うのも要注意よ〜」
参考: Active Record バリデーション | Rails ガイド
⚓セキュリティチェックリスト2本立て
- リポジトリ: eliotsykes/rails-security-checklist -- コミュニティドリブンのRails向けセキュリティチェックリスト
つっつきボイス:「2つの記事はこの間公開した記事↓で参考に挙げられていました」「1本目はあまり見たことない感じですが普通にRailsのセキュリティチェックリストとしてよさそうですね」「★も1000超えてますし😊」「RailsはとりあえずBrakemanで機械的にチェックできるセキュリティホールを全部つぶしておくのが吉」
「へぇぇ、RedcarpetにHTML
とSafe
ってあるって初めて知った😁」「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っていう脆弱性チェックサービスみたいです」「なるほど: こういうブラックボックステストやってくれるところはいろいろありますけどね😊」
「2本目↑は文字通りCTO向けの自社セキュリティチェックリスト: RailsやWebアプリ以外にも広く使える」「SaaSでなくてもいいと」
⚓Deviseのパスワードを安全に保つには
つっつきボイス:「そうそう、パスワードハッシュってこうやって$
マークのところで意味が区切られるんですよ↓」「えっ知らなかった😳構造があるんだ...」「こういうのはPHPなんかでも作られますね: フレームワークの数だけこういうのがある😎」
⚓その他Rails
- 元記事: Mac用パッケージマネージャー「Homebrew v1.8」がリリース。macOS 10.14 Mojaveを公式サポートし、El Capitanがサポートから外れる。 | AAPL Ch. -- そんなに変わってないのかな?
- 元記事: Debugging Docker -- PassengerをデバッグしていたらDockerをデバッグするはめに
⚓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
つっつきボイス:「fish使ってないしな〜」「一瞬使ってみたけどbashに戻したことあります😅」「Firは試しに動かしてみたけどところどころつっかえるかな...終了もexit
じゃなくてCtrl-Dだったし」「ま、お好きな人はどぞ〜☺️」
参考: fish shell
⚓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でも使えると書いてる」「ライブラリが今後メンテされるかどうかがちょっとコワイ🎃: こういうコアライブラリは基本的にメジャーなものを使うべきだと思いますね🤓」
- リポジトリ: crypto-rb/rbnacl
「READMEに書いてあったGPG↓、一瞬PGPに見えちゃった😅」「GPGはものすごく歴史古いですね📃」
参考: GNU Privacy Guard - Wikipedia
⚓Yabeda: Rubyアプリのinstrumentation gem(Hacklinesより)
- 元記事: Meet Yabeda: Modular framework for instrumenting Ruby applications — Martian Chronicles, Evil Martians’ team blog
- リポジトリ: yabeda-rb/yabeda
- リポジトリ: Yabeda
TechRacho記事でおなじみのEvilmartiansのブログです。
つっつきボイス:「ebay向けに作ったgemみたいです」「やべだ?」「Prometheusをこれだけ密にインテグレーションできるとしたらなかなかいいかも?」
「ははぁ、Yabedaを使ってまとめてPrometheusとかに投げられる↓ってことか: よさそう😍」
- リポジトリ: yabeda-rb/yabeda-sidekiq
- リポジトリ: yabeda-rb/yabeda-prometheus
- リポジトリ: yabeda-rb/yabeda-rails
「yabeda-muninとかないのかな😆: そしたらBPSで使える」「まぁmuninのアダプタはたぶん超楽勝で書けそう🤓: コマンド実行したら値を返すスクリプトを書けばそれでおしまいなので」「muninってそんなにシンプルなんだ!」「シェルスクリプトでも書けるぐらいなので😉」
参考: Munin
⚓その他Ruby
- 元記事: My two favorite ruby videos on youtube. - DEV Community 👩💻👨💻 -- お気に入りのRuby動画2本(Hacklinesより)
つっつきボイス:「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
- サイト: Vault by HashiCorp
「HashiCorpは結構頑張ってますね: マイクロサービスを自社で建てるみたいなことをやってる会社はHashiCorpの製品のお世話になってることが多いと思う」「おー😃」
⚓その他クラウド
つっつきボイス:「ライナスがきれいなライナスになったか😆」「寺に籠もって反省したんでしたっけ」「Richard Stallman御大がコメントを寄せてたのにはつい笑った😆」「えっ知らなかった😳」
後で探してみたところ、この辺かなと思いました↓。
参考: Richard Stallman Says Linux Code Contributions Can't Be Rescinded - Slashdot
参考: Richard M. Stallman on the Linux CoC : linux
Stallmanと言うと彼の自作の歌を思い出してしまいます↓。
GitHub Universeのフィードバックを日本からの参加者が行うイベントが来週あります。今日発表されたGitHub ActionsやGitHub Connectとかに興味を持った方は是非ご参加を。https://t.co/QAq8CUq4LW
— 及川卓也 / Takuya Oikawa (@takoratta) October 17, 2018
終わっちゃいましたが。
⚓SQL
⚓大物リリース2本立て(DB Weeklyより)
つっつきボイス:「先週PostgreSQL 11が出たのはウォッチでも簡単に書きましたが」「ぽすぐれも年1でがんがんリリースするポリシーに変えたのかな?」「昨年10月にPostgreSQL 10をリリースしてちょうど1年ですしね」「PostgreSQLはメジャーアップデートで機能を増やすというポリシーでこれまでやってきてたはず」
「そしてその後でRedis 5も出たそうです」「Redisを自分でアップグレードするとかあまり考えたことなかったナ😁」「とりあえずredisでStreamができるようになった↓というのが目を引きました」「redisは何でもできるから😋」
参考: 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
⚓JavaScript
⚓V8のソート(JavaScript Weeklyより)
記事中の「Timsort」が気になってググると、過去にJSでTimsortがバグったという記事がわらわら出てきました。
つっつきボイス:「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
「こういうグローバルな調査はもちろん大事だけど、母集団がどれぐらい偏ってるか恣意的な要素が混じってないかとかが気になるところだし😆自分たちの開発における意義としては、たとえばCIのエラー件数の推移を取るとか、コード量の増加に対してカバレッジがどう増えているかとかの方が恣意的な要素が入りづらいし実用的かなという気はしますね: Railsならrake stats
とかで取れるし」「そうかも☺️」
参考: rails アプリの統計情報を一発で取れる rake stats
を試した - yagihiro output
⚓その他HTML
- 元記事: Watch video using Picture-in-Picture | Web | Google Developers -- 動画を「ピクチャ・イン・ピクチャ」で表示するテクニック(Frontend Focusより)
つっつきボイス:「お、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でできるかも?」「ま、これは数学におけるワンライナーみたいなもんだし🤓」「たしかに〜」「フーリエ展開かマクローリン展開かテイラー展開のどれかでできそうな気はするんだけどなー」「数学科だったけど忘れたー😇」「忘れたー😇」
ふと、昔ちら見したジョゼフ・ニーダム「中国の科学と文明」を連想しました。
⚓その他
⚓AI丸投げ開発とは
元記事のタイトルが秀逸だと思いました。それだけでした。
⚓スパイチップその後
つっつきボイス:「チップは置けてもどうやってデータを抜くんだろうなと気になってたけどやっぱり」「実はチップを人力で回収するとか😆」「それならわかるけど、メモリも内蔵してなさそうだしな〜謎🤔」
「まあ意表を衝いたデータの抜き方ってときどき出現しますけどね: クランプメーター(アンペア計)で配電盤にアクセスすることで隣の部屋のディスプレイ表示を電源ラインから取り出す裏技とかありましたし」「それできそう!」「電源ラインのノイズからデータを取り出すとは」「天才だよな😆」「そうやっていろんな技があったりするんで、スパイチップを一概に否定するのは難しい気はしますね🤓」
⚓その他のその他
つっつきボイス:「記事に出てくるものがいろいろなつかしくてつい😅」「当時は大学のコンピュータ部とかでこんな感じで凄いゲームを作ったりしてましたね☺️」
⚓番外
⚓いかにもじゃない方が好き
つっつきボイス:「トンガッたデザインにすると陳腐化早そうですよね」「電脳メガネって言葉が既に恥ずかしいぞっ😆」「😆」「網膜に直接投影するタイプのもあった気がする」「それ確実そうですね」「目に何か差し込むのかとおもた👁」
参考: 網膜投影型ARグラスの一般向け受注が開始 | Think IT(シンクイット)
⚓教師データなしで動いたロボットハンド
つっつきボイス:「やってることはクールなんですが、ナレーションの英語がとってもインド訛りなのが気になって😆」「お、インドにしてはゆっくり喋ってる方かな: カンファレンスとかでこの数倍の速さで喋られると聞き取り大変😅」「教師データなしというより自分で教師データを作りながら学習してるんじゃないかな🤔」
今回は以上です。今度の公開つっつき会でお会いしましょう!😄
おたより発掘
あとで読む。サラッと読んだけど雑談風な記事がいつもよい - 週刊Railsウォッチ20181029: 特集『肥大化したActiveRecordリファクタリング7つの方法』今ならどうなる?Redis 5のストリーム機能他 https://t.co/GJma3SDHED
— 干し肉 (@yhirano55) October 29, 2018
バックナンバー(2018年度後半)
週刊Railsウォッチ(20181022)Railsの名前空間地獄とrequire_dependency、PostgreSQL 11がリリース、clean-rails.orgほか
- 20181015 Rails初心者と一発でバレる書き方、次のVue.js構想、RubyのOpenStruct、Twilioほか
- 20181001 Railsアップグレード記事と各種支援ツール、CLI向けRubyワンライナー集、Rubyアプリをワンバイナリ化ほか
- 20180925 Rails大規模支払サービス開発のノウハウ、RailsのMySQLがutf8mb4に移行、Rpush gemほか
- 20180918 ビューテンプレート探索が高速化、mini_scheduler gem、レガシコントローラのリファクタリングほか
- 20180910 公開つっつき会#2、RSpecは何を参考にするか、イベントソーシング、marginalia gem、負荷テストツールvegetaほか
- 20180903 次世代アップローダーgem「Shrine」、RSpecをどこまでDRYに書くか、Rubyのmainオブジェクトの秘密、GitLabのCookie利用許諾機能はエライほか
- 20180827 Ruby Prize 2018募集開始、Interactor gemとReader Object、書籍『Real World HTTP』、Basecampのヒルチャート機能ほか
- 20180820 Railsで構築されたサイト40選、Deviseはつらいよ、ARのスコープとクラスメソッドの使い分けほか
- 20180813 Rails 5.2.1リリース、sanitize_sql_arrayは5.2からpublicだった、Dev.toがRailsアプリのソースを公開ほか
- 20180806 Rails 5.2.1.rc1リリース、Railsガイド日本語版が5.1に対応、Regexp#match?ほか
- 20180723 Railsdm Day 3 Extremeを後追い、PSDにはZeplin.io、好みの分かれるJSX、負荷テストツール比較ほか
- 20180709 Rails Developers Meetup Day 3 Extreme今週末開催、RailsのSTI/キャッシュ/添付ファイル/Redis/PDF出力、ECMAScript 2018、プロフェッショナルIPv6ほか
- 20180702 Ruby 2.2メンテ正式終了、Ransackがつらくなるとき、書籍『Domain-Driven Rails』、GitHubの高可用MySQLほか
- 20180622 Railsの需要未だ巨大、Unicode 11.0リリース、WebDriverがW3Cで勧告、Flutter.io、2封筒問題ほか
- 20180615 TTY gemとHTTPClient gemは優秀、Rubyの謎フリップフロップ、ちょいゆるRubyスタイルガイドほか
- 20180608 特集「RubyKaigi 2018後の祭り」、
Enumerable#index_with
は優秀、コントローラから@
を消し去るほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。