Movatterモバイル変換


[0]ホーム

URL:


Tech Rachoエンジニアの「?」を「!」に。
  1. TOP
  2. Ruby / Rails関連
  3. 週刊Railsウォッチ(20191015)スライド「Rails Performance issues and Solutions」を見る、dirtyに*_previously_was が追加、Sidekiq 6.0.1ほか
  • Ruby / Rails関連

週刊Railsウォッチ(20191015)スライド「Rails Performance issues and Solutions」を見る、dirtyに*_previously_was が追加、Sidekiq 6.0.1ほか

こんにちは、hachi8833です。台風前のつっつきでしたので、エントリを減らし気味にしてみました🙇。

台風19号の最大瞬間風速は75mらしく、これを時速に直すと270km/h。
東海道新幹線の最高速度が285km/h、飛行機の離陸時の速度が240〜300km/hらしいので、新幹線や飛行機並みのスピードでいろんなものが飛んできます。ヤバい。https://t.co/iKTTEgf5Nzhttps://t.co/Ic8ky9GPsUhttps://t.co/Ic8ky9GPsUpic.twitter.com/Y5TpNX2Dvg

— Junichi Ito (伊藤淳一) (@jnchito)October 9, 2019


つっつきボイス:「jnchitoさんは関西の方でしたね☺️」「mapで風速を秒速から時速に変換してる」

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

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

今回は公式情報を中心に見繕いました。

なお、6.0.1マイルストーンも見てみましたが、「再現できない」「自分のコードが間違ってた」でcloseされているケースがいくつか見当たりました。

新機能: dirtyトラッキング用*_previously_wasを追加

なおマージされたのは8/2です。

# 同PRよりpirate.update(catchphrase: "Ahoy!")pirate.previous_changes["catchphrase"] # => ["Thar She Blows!", "Ahoy!"]pirate.catchphrase_previously_was # => "Thar She Blows!"
# activemodel/lib/active_model/dirty.rb#L125    included do      attribute_method_suffix "_changed?", "_change", "_will_change!", "_was"-     attribute_method_suffix "_previously_changed?", "_previous_change"+     attribute_method_suffix "_previously_changed?", "_previous_change", "_previously_was"      attribute_method_affix prefix: "restore_", suffix: "!"    end...+   # Dispatch target for <tt>*_previously_was</tt> attribute methods.+   def attribute_previously_was(attr_name) # :nodoc:+     mutations_before_last_save.original_value(attr_name.to_s)+   end

API:ActiveModel::Dirty
参考:1.4 Dirtyモジュール -- Active Model の基礎 - Rails ガイド


つっつきボイス:「またdirtyに新しいメソッドが生えるのね😆」「DHHが自分でツイートしていたような気がします」

探しましたがDHHのツイートはありませんでした😅。代わりに以下を貼っておきます↓。

New attribute methods, regex matching and more!: Originally appeared on Riding Rails. Hello! Tim here with the latest scoop on Ruby on Rails! New *_previously_was attribute methods! Your models just got a sprinkling of a little extra sugar. For any given…https://t.co/l3l7qqDqAHpic.twitter.com/LrdOri2h6O

— Malibu IT Labs (@it_malibu)October 7, 2019

新機能: MySQLでmatches_regexdoes_not_match_regexpが使えるようになった

# 同PRよりusers = User.arel_table;# 全gmailユーザーを検索users = User.arel_table; User.where(users[:email].matches_regexp('(.*)\@gmail.com'))# gmail以外の全ユーザーを検索users = User.arel_table; User.where(users[:email].does_not_match_regexp('(.*)\@gmai
# activerecord/lib/arel/visitors/mysql.rb#L51+       def visit_Arel_Nodes_Regexp(o, collector)+         infix_value o, collector, " REGEXP "+       end++       def visit_Arel_Nodes_NotRegexp(o, collector)+         infix_value o, collector, " NOT REGEXP "+       end

つっつきボイス:「ActiveRecordで#matches_regexpを使った正規表現比較がMySQLでもできるようになった🎉」「今までもwhereの中に書いたりしてたけど、エスケープしてくれるのがありがたい😋「PostgreSQL版の実装は前からあったみたいで、今回はMySQLでも使えるようにしたそうです」

調べてみるとPostgreSQL版は2年前に入っていました↓。

# https://github.com/rails/rails/blob/master/activerecord/lib/arel/visitors/postgresql.rb#L29        def visit_Arel_Nodes_Regexp(o, collector)          op = o.case_sensitive ? " ~ " : " ~* "          infix_value o, collector, op        end        def visit_Arel_Nodes_NotRegexp(o, collector)          op = o.case_sensitive ? " !~ " : " !~* "          infix_value o, collector, op        end

「SQL文の中で正規表現が使いたくなることってたまにありますよね?」「今どきのRDBではたいてい使えますけど😋」「あ、SQLite3で正規表現をちょっとだけ使おうとしたときが割と面倒でした😆」「SQLite3にはなさそう😆」「一応あるにはありました↓」

参考:SQLite で正規表現を使う - しょぼんメモリ (´・ω・`)

「まあRDBの正規表現を使いすぎるとちゃんとした速度が出なくなったり、インデックスが効いたり効かなかったりすることもあるので微妙ですけど😆」「そうですよね」「コレーション(照合順序)とかも影響する可能性ありそうですし😅」

参考: PostgreSQL 11.5ドキュメント23.2. 照合順序サポート

joinsのorderをできるだけ維持するよう修正

修正量が多めだったのでソースは貼りませんでした。


つっつきボイス:「最近kamipoさんたちが苦しみ続けていたjoinsのorderの件が『できるだけ維持する』方向でひとまず収束したようです」「ここはたしかに厄介な部分...😅」「Active Recordのオブジェクトとしてどう解釈されるかまで考えたうえでSQL文も見ないといけないのはつらい🥺」

RackのMigration::CheckPendingFileUpdateCheckerを使うようにしてマイグレーションのパフォーマンスを大きく改善

ここからはマージされたプルリクから見繕いました。最近は大半がドキュメントの微修正です。

# 改修前$ be ruby benchmark.rbWarming up --------------------------------------   CheckPending#call    11.000  i/100msCalculating -------------------------------------   CheckPending#call    135.510  (±12.5%) i/s -    671.000  in   5.083931s
# 改修後: file_watcher == FileUpdateCheckerの場合$ be ruby benchmark.rbWarming up --------------------------------------   CheckPending#call    34.000  i/100msCalculating -------------------------------------   CheckPending#call    348.063  (±18.1%) i/s -      1.666k in   5.024624s
# 改修後: file_watcher == EventedFileUpdateCheckerの場合$ be ruby benchmark.rbWarming up --------------------------------------   CheckPending#call   128.936k i/100msCalculating -------------------------------------   CheckPending#call      1.884M (± 2.5%) i/s -      9.412M in   5.000561s

従来はlast_migration.mtimeの値で変更を監視していたが、ActiveSupport::FileUpdateCheckerEventedFileUpdateChecker(新しいアプリではこちらがデフォルトになる)を用いてパフォーマンスを大幅に向上させた。
同PRより大意


つっつきボイス:「この間も話に出たファイルウォッチャー(ウォッチ20190930)を使ってマイグレーションのpendingチェックを速くしたそうです」「お〜なるほど、これでファイル更新チェックのために毎回全なめしなくてよくなった😋」「pendingチェックたしかに今まで遅かったですね」「productionも含めてRailsサーバーの起動が速くなりそう👍」

「この#37395と同じお題で以前に#29759↓でチャレンジしたときはうまくいかなかったのを再挑戦して今度はうまくいったそうです」「こういうのはどうやってテストするかという問題もありますし、Railsはマルチワーカーで動くからそこでもちゃんと動かないといけないでしょうし☺️」

(ドキュメント)autosaveの関連付けの振る舞いについて注意点を追加

レコード自身が変更された場合、autosaveは永続化済み関連付けレコードでのみトリガーされる。これは循環した関連付けバリデーションによるSystemStackErrorから保護するのが目的。例外が1つあって、カスタムのバリデーションコンテキストが使われていると、関連付けられたレコードのバリデーションが常に発火する。
同PRより大意


つっつきボイス:「APIドキュメントに注意事項が1つ追加されていました」「circular association validationって😆」「循環参照があるとautosaveの挙動がおかしくなるでしょうね☺️」「ただしカスタムのバリデーションコンテキストが使われているとバリデーションが常に発火すると」

参考:4.3.2.2:has_manyautosave -- Active Record の関連付け - Rails ガイド

# 5a3e34eより  def test_validations_still_fire_on_unchanged_association_with_custom_validation_context    firm_with_low_credit = Firm.create!(name: "Something", account: Account.new(credit_limit: 50))    assert firm_with_low_credit.valid?    assert_not firm_with_low_credit.valid?(:bank_loan)  end

5a3e34ecreate!でやってるこのあたり↑がそうかな」「おぉ?」「中でAccount.newしているものがsaveされないとidが確定しないからcreate!できなくなりますね」「あ〜なるほど!」「こういうのがカスタムバリデーションコンテキストでのautosaveということだと思います☺️: 中のAccountが外のFirmにhas_manyしているときは、firm.account_idをセットするために中のものから先に作らないといけないのでAccount.newが自動でsaveされると」「こういう状態を何て言えばいいんでしたっけ?😅」「循環でもデッドロックでもない、普通の依存関係ですね☺️」

Rails

スライド: amatsudaさんの「Rails Performance issues and Solutions」

Just published my slides deck for my opening keynote "Rails Performance Issues and Solutions" at RubyConf Indonesia 2019!https://t.co/Gxa4btN9n7#RubyconfID

— Akira Matsuda (@a_matsuda)September 29, 2019


つっつきボイス:「この間の公開つっつきでこちらのスライドを取り上げるのを忘れていました😅」「そうそう、この間の銀座Rails#13↓でamatsudaさんが発表したRailsパフォーマンス話もこれに含まれていると思います😋」「スライドはその後のRubyConf Indonesia 2019でのものだそうです」「つか銀座Railsのスライドはそっち用のドラフトだったのかも😆」「銀座Railsのときにも資料書いてる途中だって言ってましたね☺️」

銀座Rails#13で「出張Railsウォッチ」発表させていただきました

「このスライドでもRails 6でのrails newでは--skip-spring--skip-bootsnapしてますが↓、銀座Railsのときにも--skip-action-textでAction Textをスキップすることが重要という話がありましたね😆」「え?😅」「今のAction Textが半端なく重いのでとりあえず無効にしておきましょう、だそうです😆」

「銀座Railsのときにマジで面白かったのはこの辺の計測の話でした❤️」「どんなお話でした?」「まあ実際のアプリでベンチマーク取るときはcurlとかでやればいいんですけど、Railsフレームワークのどこにボトルネックがあるのかを調べるときには、こんなふうに↓イニシャライザで直接モンキーパッチを当ててやる方がいいということでした」「おぉ〜!」「こうすればRackの処理の重さとかに影響されなくなるので純粋にRailsコードの速度を測れるようになるからいいよって😋」「これいいノウハウですね😍」「ここではprependで直接差し込んでます」

「Apache Bench(ab)とかで測定すると、どうしてもRails以外のボトルネックも出てきたりしてしまいますが、この方法ならRailsのコードだけにフォーカスできますね👍」「あとはアタッチする場所を少しずつ変えて試す↓: パッチのコードは他の場所でもほぼそのまま使い回せるので、うまい方法だと思います😋」「いいですね〜😋」

参考:Apache Benchでサクッと性能テスト - Qiita

「次がRailsのアロケーションを削減する話」「『先週の改修』でもamatsudaさんがやってるのを見てきましたね」「こうやってProf.memしてプロファイラの結果を眺めて、これはちょっと多くね?と思ったところをひたすら地道に直していくというのをやってるそうです↓」「ふむぅ」

「そうそう、使ってないはずのAction Textエンジンがなぜかいるという話も↓😆」「おおっと😆」

「その修正方法はというと、require 'rails/all'をやめてAction Textだけを除いたものを自力で書くと↓🤣」「🤣」「Action Textをrequireするだけで重くなるからRails 6ではこうするとこれだけアロケーションが減って速くなるよと」「何ということでしょう😆」


rails newする段階でAction Textを入れないようにする方法ってありますよね?🤔」「あります」「でもたぶんapplication.rbでrequire 'rails/all'するとAction Textも入っちゃうんだと思います: というのもRailsのgemspecにはAction Textも入ってるはずなので、Gemfileでrequire "rails"と書かれている状態でbundle installした段階ではAction Textのgemも入ってくるはずで、その状態でrails newするとapplication.rbでrequire 'rails/all'となって入ってきちゃうと思います」「あ〜」

後で、ごく最近のRails 6で--skip-action-textなどを指定してrails newしたもので見てみるとapplication.rbでは自動的に除外されていますね↓😋。rails newで何もスキップしない場合はrequire 'rails/all'になります。rails newした後から機能を外す場合は自分でrequire周りを変える必要がありますね。

require_relative 'boot'require "rails"# Pick the frameworks you want:require "active_model/railtie"require "active_job/railtie"require "active_record/railtie"require "active_storage/engine"require "action_controller/railtie"# require "action_mailer/railtie"# require "action_mailbox/engine"# require "action_text/engine"require "action_view/railtie"# require "action_cable/engine"# require "sprockets/railtie"require "rails/test_unit/railtie"

参考:Rails 6.0.0 performance regression because of ActionText::Engine hook · Issue #36963 · rails/rails -- open

「Action Textはrequireから外さないとアロケーションされてしまうらしい🤔」「amatsudaさんが#36963↑を投げてくれて『Rails 6.0.1で直ることを期待』と」「Action Text以外のオプション機能についてはrequireから外してもなぜかアロケーションは変わらないと」

↓こちらのissueも関連してそうです。

参考:ActionText forces all apps to include an ActionController::Base subclass · Issue #37183 · rails/rails -- open


「後は細かいところだと=~よりmatch?の方が速いとか↓」「そういえば今のRubyはmatch?の方が速いんでした」「match?は余分なオブジェクトに触らない分速いとかそんな感じ」

「ハッシュもHash#mergeより添字アクセスのHash#[]=の方が速い↓」

「同じくHash#fetchよりHash#[] || defaultの方が速い↓」「上もそうだけど、前者はメモリがアロケーションされるけど後者はされないのね」「Hash#[]はCRubyのコアのところに直接つながっているはずだけど、Hash#mergeHash#fetchはメソッド呼び出しだから、たぶん仮引数代入とかが発生するんじゃないかしら🤔」「おぉ」

「まさにマイクロオプティマイゼーションを積み上げていく作業😳」「塵も積もれば5〜10%のアロケーション削減が見込まれると🎉」「このスライドはじっくり追いかけていくといろいろ発見がありますね❤️」

「この辺はテンプレートエンジンの話↓」「hamlは速いぜと😋」「k0kubunさんも記事にしてたヤツですね(ウォッチ20190925)」「stringの式展開にすると速いという話とか」

「amatsudaさんによると実はI18nが重いんですよ↓」「おぉ?」「I18nだけは式展開にできないのでどうしてもメソッド呼び出しが残っちゃう」「なるほど!」

「なのでロケールごとにI18nのキャッシュを作って高速化しようとしてるそうです↓: 銀座Railsで見たときはまだ作業中と言ってたかな」「これもすごく有用な話ですね😋」「こういう積み重ねでメモリアロケーションをじわじわ減らしていると」「すげ〜!」「Railsはメモリをめちゃ食うという印象があったりするので、こういうところが改善されていくのはいいですね〜☺️」


Ruby 2.6.4を入れるとRailsで使うと遅くなる、知見じゃん#ginzarails

— sue445 (@sue445)September 12, 2019

「上のツイート↑はこの間のウォッチでは裏を取れなくて見送った話でした」「そうそう、Ruby 2.6.4だとMonitor#synchronizeでRailsのベンチマークが遅くなるそうです↓」

参考:class Monitor (Ruby 2.6.0)

Rails 6のAR associationとscopingの変更

ruby-jp Slackで知りました。


つっつきボイス:「上の記事はもともと論理削除が使われていたコードのつらみから始まったとのことで、今日はつっつきに出られないkazzさんにこの記事を見せたら苦笑いしてました😅」

しかし、Rails 6では…
仕様が変更された為、先程のコードはそのままでは動きません。具体的には、

Blog.not_deleted.scoping do  BlogComment.where(blog_id: 1).blogend

nil を返しません。BlogComment.blog のAssociation解決時に実行されるBlog モデルへのSELECTクエリへのスコープがリセットされ、deleted_at IS NULL の条件が消える為です。
同記事より

参考:Association loading isn't to be affected by scoping consistently by kamipo · Pull Request #35868 · rails/rails

「Rails 6では上のように変わってたそうです」「へ〜、たしかにassociationのタイミングで違うものを返されるとビビるからマジ止めてほしい😭」「associationの読み込みはdefault_scopeでは有効だけどunscope以外の普通のスコープだと有効じゃなくなったとは😳」「そういえばRailsアップグレードガイド↓でこの変更を翻訳した覚えがありませんでした」

参考:Rails アップグレードガイド - Rails ガイド

「まあscoped chainはやりすぎるとつらくなるし😢」「やっぱこういうのはテストを書いておくべきだな〜: でないとこういうbreaking changesが起きたときに死ぬ😇」「踏んだときに原因がわかりにくそう😅」

「記事はやむを得ずdefault_scopeで対応することにしてますね」「default_scope使わないぞキャンペーンもしつつ😆」「default_scopeは止めた方がいいかと😆」

Railsのdefault_scopeは使うな、絶対(翻訳)


以下はつっつきの後で見つけたツイートです↓。

与太話をすると、default_scopeとscopingは無限のissueを産む機能でメンテナに嫌われ見放されてたけど、k0kubunさんのテクニックでjoins/eager_loadのdefault_scopeを無効化できる変更を通すことに成功したのがきっかけでどんなscopingも受け付けると無限のコーナーケース(無限ループするとか)が産まれ

— Ryuta Kamizono (@kamipo)September 26, 2019

throughアソシエーションじゃない遅延ロードだけなぜかscopingの影響を受けるテストが存在してて当時のわいの徳ではそれを覆す気合いがなかったからそこだけ非互換変更を入れず一貫してない挙動を許容する道を選んだのや当時は。その後無限のやる気を持つメンテナ(わい)がscopingのバグ直しまくるため

— Ryuta Kamizono (@kamipo)September 26, 2019

手ぬいたが一応CHANGELOG書いたけど、めっちゃ偏執的にやるならこれですらもdeprecation warning出したらよかったですね。でもわいも人間やし無限にバグ直しまくってると疲れてちょっと手ぬいたってええかなってなるときもあるねん。それは広い心で受け止めてくれたらうれしい、ほんとすまんかったわ。

— Ryuta Kamizono (@kamipo)September 26, 2019

Sidekiqが6.0.1で高速化(Ruby Weeklyより)


つっつきボイス:「10〜15%速くなったはず、とありますね」「タグを付けられるようになってる↓」「Pro版だとこれで絞り込めるそうです」

# changelogよりclass MyWorker  include Sidekiq::Worker  sidekiq_options tags: ['bank-ops', 'alpha']  ...end

find_jobもかなり速くなってる↓」

zscan 0.179366 0.047727 0.227093 ( 1.161376)
enum 8.522311 0.419826 8.942137 ( 9.785079)

「結局Sidekiqをナマで使うことになるのかな〜: Active Job越しにやると機能が足りなかったりしますし😅」「そんな雰囲気ですね」「Rails way的には本来Active Jobでジョブワーカーを抽象化するんですけど、ジョブワーカーの種類によって機能が違うから特定のジョブワーカーの機能を使おうと思うとActive Job経由できれいにやろうとするより生のSidekiqを使うことになりそうかな〜🤔」「ラッパー越しだと靴の上から足を掻くみたいになっちゃうんですね😳」「単純な作業ならラッパー越しでもいいんですけど、ジョブの制御までやり始めるとそうなりがち😢」「うーむ」

「ジョブで名前空間を使いたいとかプライオリティ付きのキューとかは、ジョブワーカーによってできるものとできないものがあったと思いますし」「ジョブワーカーというとこのsidekiqの他にdelayed_jobと、あと何だっけ?」「思い出せない😅」「最近sidekiq使うこと多いし😆」「あ、resqueか!」

「sidekiqのリリースノートを見ると、なぜか『ダークモードに対応』ってありますけど😆」「sidekiqのWeb UIには割とお世話になりますし、マウントするだけでWeb UIを使えるのは便利😋」「『もっとイケてるデザイン募集』ともあります🤣」「たしかにあんまりイケてないけど🤣」「まああれで十分ではある☺️」

ARモデル内でクエリロジックを共有する(Ruby Weeklyより)

# 同記事よりclass User < ApplicationRecord  # our class method from above  def self.can_receive_alerts    where(receives_sms_alerts: true).      or(where(receives_email_alerts: true)).      joins(:alert_configurations).      distinct  end  # our new instance method which builds on the class method  def can_receive_alerts?    self.class.can_receive_alerts.where(id: id).exists?  endend

つっつきボイス:「自分も先週見つけていた記事でしたがRuby Weeklyに先越されました😢」「コードの再利用ですね☺️:self.can_receive_alertsで作った条件をインスタンスメソッドでちょっと変えてスコープ的に再利用すると」「kazzさんともこの記事で雑談してたんですが今思い出せない😅」「クラスメソッドで使った条件にwhere(id: id).exists?を足してインスタンスメソッドでも使いたいという感じなので、そんなに難しい話ではないですね」「おぉ」「スコープにこういう感じで条件を付けることはよくあるので、インスタンスメソッドでその条件に合っているかを確認するのに同じことをもう一回書かずにやれるよということで☺️」

sprockets 4.0.0がリリース

これもruby-jp Slackで知りました。キーワード引数周りの修正やアロケーション削減、脆弱性修正などが行われました。Ruby 2.5以降のみがサポート対象になりました。


つっつきボイス:「sprocketや〜😆」「Webpackに押されてるのかと思ったらいろいろやってるんですね」「お、JSのSource Mapが使えるようになってるし😋」「3.xにはなかったのか〜」

参考:WTF is a Source Map

  "version":3,  "file":"application.js",  "mappings": "AAAA;AACA;AACA;#...",    "sources": [      "jquery.source-56e843a66b2bf7188ac2f4c81df61608843ce144bd5aa66c2df4783fba85e8ef.js",      "jquery_ujs.source-e87806d0cf4489aeb1bb7288016024e8de67fd18db693fe026fe3907581e53cd.js",      "local-time.source-b04c907dd31a0e26964f63c82418cbee05740c63015392ea4eb7a071a86866ab.js"    ],    "names":[]}

「manifest.jsも対応してるし!欲しかったものが割と増えてる気がする❤️」「デフォルトでES6をサポートですって」

// app/assets/config/manifest.js////= link application.css//= link marketing.css////= link application.js

「まあES6でやるならWebpackでいいんじゃね?とも思いますが😆」「Sprocketsで十分という人にはありがたそうですね」「RubyのコードでJavaScriptコードを生成したい人はSprocketsを使いたいでしょうね」「というと?」「JavaScriptのコードの中に、パーシャル的にRubyのコードが埋まっているようなコードを書きたいときとか: SprocketsならRubyのコンテキストで処理できるので😋」「おぉ〜」「まあ今となってはあまりやりませんし、manifest.jsがあるならそっちに入れるという手もありますし」

「Rubyエンジニアが多いプロジェクトなら、Rubyが気軽に使えるという意味でSprocketsがいいかも: WebpackにはRubyを処理させられないので(探せばあるかもしれませんが😆)」

「Reactとか使わないんだったらSprocketsでもよさそうですね🤔」「まあそれでもいいんですけど、要はフロントエンドのコードを誰がやるかがポイントかも😆: フロントエンジニアはSprocketsの面倒は見たくないでしょうから彼らが慣れているWebpackの方がいい、とかね」「ふ〜む」「フロントエンジニアにしてみれば、SprocketsのためだけにRailsを勉強するとなるとオーバーヘッドがヤバいですし😆」「たしかに😆」「逆にみんなRailsエンジニアならSprocketsでいいでしょうし、Webpackerがむしろわけわからんかもしれませんし」

Ruby

Ruby 2.7のキーワード引数変更


つっつきボイス:「例の#14183↓がウルトラ長くて私には要約できそうになくて😂」「またしかに😆」「まだ読めてませんが、この記事で端的にまとまってるといいなと願っています🙏: ちなみにこのblog.saeloun.comブログのRuby記事はいいですね😋」

ruby/specに新しいexpectationが追加

これもruby-jp Slackで見かけました。

describe "String#start_with?" do  it "returns true only if beginning match" do    "hello".start_with?('hel').should == true  endend

つっつきボイス:「ruby/specって何だろうと思ったら、Ruby自身のテストのためのものみたいです」「RSpecライクというか☺️」「それを動かすのがMSpecというツールだそうです」「RSpecをいっぱい書いている人がRubyのspecも書きたい、とかそういう感じ?😆」「自分なら書かないかな〜😆」「言語のチェックならアサーションとかでやる方がシンプルになりそうですし☺️」

参考:ruby/spec: The Ruby Spec Suite aka ruby/spec
参考:ruby/mspec: RSpec-like test runner for the Ruby Spec Suite

「なおRSpecも3.9がリリースされたそうです」「お、システムspecのジェネレータができた❤️」「今までなかったんですね?」「まあジェネレータがなかったというだけで、ディレクトリは前からありますし」「type: :systemで指定するのか〜」

RSpec 3.9がリリースされていますね。小規模なアップデートが中心ですが、個人的にはrspec-railsでシステムスペックのジェネレータが追加されたのが一番大きいニュースかも!
ただ、このbeforeブロックは別になくても良い気がするな・・・。https://t.co/fVyLfcv6CJpic.twitter.com/CCDGFGfoHA

— Junichi Ito (伊藤淳一) (@jnchito)October 9, 2019

testrocket: インラインでテストを書きたい(Ruby Weeklyより)

# 同リポジトリよりrequire 'testrocket'using TestRocket# BASIC USAGE# +-> { block that should succeed }# --> { block that should fail }+-> { Die.new(2) }--> { raise }+-> { 2 + 2 == 4 }# These two tests will deliberately fail+-> { raise }--> { true }# A 'pending' test~-> { "this is a pending test" }# A description!-> { "use this for descriptive output and to separate your test parts" }

つっつきボイス:「テストを本編コードにインラインで書きたいそうです」「スーパーシンプルであると😆」

「むむ、こういう書き方をする言語って他にもあった気がする!」「見覚えありますね🤔」「オプションつけて実行するとテストが走って、付けないと普通に動くみたいなの、あった」「何だったかな〜?」

「こういうのをうまく設計すれば、APIドキュメントとしても成立しないかなって思ったり」「いや〜邪魔😆」「邪魔😆」「そういう方向よりも、JetBrainsのIDEみたいにコードからテストコードに即ジャンプできるとかマウスオーバーでテストコードが見えるみたいな方がうれしい気がしますけどっ😆」「エンジニアにとってエディタの行数という貴重な有限のスペースを他に使いたくないですし😆」

「こういうインラインなアサーションを書く言語...Javaにあった!」「あ〜そうだった!」

参考:- JUnit 実践講座 - シナリオベースのテストケースの書き方

// 同記事よりpublic class LoginFormTest extends TestCase{    public void test() throws Exception    {        LoginForm form = new LoginForm();        form.setUserId("user1");        form.setPassword("password1");        form.execute();        assertEquals("こんにちは,ユーザ1さん!", form.getMessage());    }}

その他Ruby

去年参加させていただいたのですが、確か女性と男性の比率が6:4ぐらいだったと思います。それでさえいつもと違う居心地だったので、男性にとっても、普段勉強会で圧倒的少数の女性がどんな居心地なのかを少しでも知るいい機会だと思います。https://t.co/34nSbfknDh

— Sho Nagata (@s_naga03)October 8, 2019

言語・ツール

Bashヒストリーの便利ワザ

Love this kind of posts, I feel my productivity has increased by 1% 😆 - 7 Bash history shortcuts you will actually use by@ianmiellhttps://t.co/RIXhD47AnG

— Stan Lo (@_st0012)October 8, 2019


つっつきボイス:「!$は知らないな〜」「!:なんちゃらは使うこともあるかな」「!:0はコマンド自身で、!:1以降が引数になる」「知りませんでした😅」

$ !:0 !:1 !:3 !:2tar -cvf afolder.tar afolder

!$:hは知らないな〜」「前回のコマンドの引数の親ディレクトリを取れるらしい」「挙動がよくわからないうちにこの辺を使うのはコワいかも😅」

$ tar -cvf system.tar /etc/system tar: /etc/system: Cannot stat: No such file or directory tar: Error exit delayed from previous errors.$ cd !$:hcd /etc

「コマンド履歴を当てにしすぎてると、ある日履歴が吹っ飛んで悲しい思いをしたりしますよね😅」「rsyncとかであるある😅」

その他

awesome-for-beginners: 初心者に優しいオープンソースプロジェクトリスト


つっつきボイス:「Gobyの@st0012さんがここにGobyも登録したいと言ってて知りました: 初心者にとって敷居が低いプロジェクトの言語別リストだそうです」「Hanamiも入ってる🌸」「優しいというか比較的開かれたコミュニティという感じでしょうね☺️」

「Rubyのohai↓もリストにありますね」「ohaiって何でしょう?」「CPUとかメモリみたいな実行環境を詳しくプロファイリングするヤツですね」「へ〜!😳」「ChefとかAnsibleで、たとえばメモリの何割をconfigに使うかとか、Railsのワーカー数とかを動的に指定するときなんかに使えます😎」

参考:About Ohai — Chef Docs

{  "filesystem" => {    "/dev/disk0s2" => {      "size" => "10mb"    },    "map - autohome" => {      "size" => "10mb"    }  },  "network" => {    "interfaces" => {      "eth0" => {...},      "eth1" => {...},    }  }}

「Ohaiにとっては、新しい環境が出てきたときにそれを足してくれるだけでありがたいので、コミットしやすいんでしょうね☺️」「なるほど!」「だからすご〜くマイナーなディストリとかの環境を追加すればそれだけで喜んでもらえますよきっと😋」

「あれ?Gobyもリストに入ってますけど😆」「あホントだ!、いつの間に😳」「早業😆」

クンロクモデムが100万円の時代

9600bpsのモデムが100万円をきって、購入の稟議書が常務決裁で良くなったころから。https://t.co/JtHatCYbrn

— 河野太郎 (@konotarogomame)October 7, 2019

遠い昔に雑誌で音響カプラの写真を見たとき、何に使うのかわからなかったのを思い出しました。

参考:音響カプラ - Wikipedia


つっつきボイス:「この辺はおっさん話ですみません😅」「カプラはさすがに知らないわ〜😆」「電話の受話器に無理やりマイクとスピーカーをはめ込んでデータ通信するという原始的なヤツです😆」

「そういえばモデムの時代にも、モデムの音を録音されるとパスワード情報を抜き取られるなんて話がありましたね🤣」「あ〜たしかに可能だ🤣」「モデムのピ〜ガガ〜って音にはデータが全部乗ってるから、録音しちゃえばパスワードも含めて復号できちゃいます☺️」「デジタルデータを音にエンコード・デコードしてるだけだから、もともとそういうものですし😆」

番外

今度はWi-Fiで


つっつきボイス:「この方面の研究は割と前からありますね☺️」「ありますね〜☺️」「そうでしたか!😳」「データソースは物珍しいけど内容はよくある感☺️」「それを実際に実装して動かしたのはスゴい💪」「恣意的な部分も相当ありそうですが😆」「研究ってそんなもんです🤣」「一般性なくても『この人かどうかさえわかればいい』とかかもしれませんね😆」


今回は以上です。

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

週刊Railsウォッチ(20191008後編)Ruby 2.7のInteger#[]でバイナリチェック、rubyzip gemは強力、13KBのJavaScriptゲームほか

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

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

Rails公式ニュース

Ruby Weekly


この記事を書いた人

hachi8833

X:@hachi8833GitHub:@hachi8833コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。これまでにRuby on Rails チュートリアル第2版のコンテンツ監修、Railsガイドのコンテンツ作成を担当。かと思うと、正規表現の粋を尽くした日本語エラーチェックサービスenno.jpを運営。Claude Codeに夢中になりすぎないための方法を模索中。ブログ:note.com/hachi8833Amazonウィッシュリスト:https://bit.ly/32aAmiI

hachi8833の書いた記事一覧へ

本記事の内容へのお問い合せはTwitterで@techrachoへMentionまたはDMにてご連絡頂くか、運営会社であるBPS株式会社のお問い合せフォームよりお問い合せ下さい。

Our Services

各種サービスのご依頼やお問い合わせなど、お気軽にご相談ください。

Our Products

製品のご利用希望や疑問・質問など、お気軽にご相談ください。

Recruit & Contacts

お問い合わせ、採用へのお申し込みはこちらから。

積極採用中 開発エンジニアCONTACT

関連記事

CONTACT

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

[8]ページ先頭

©2009-2025 Movatter.jp