あけましておめでとうございます、hachi8833です。2017年最初のRailsウォッチいってみましょう。
年末のRubyとRailsのリリース後ということもあり、Ruby 公式とRails公式はニュースなしでした。
データベースのパフォーマンスを損なうRailsコードの書き方
PostgreSQLをお題にしたデータベースパフォーマンスについての話題です。Railsはあまり関係ない感じのようでした。
パフォーマンス調査のためにexplain
コマンドなどでクエリプランを詳しく調べることの重要性、SQLの書き方によってどのようにパフォーマンスが変わるか、クエリプランはDBMS(PostgreSQLかMySQLかなど)やクエリオプティマイザによって異なる(スキーマとクエリで確定するタイプや、データによって変わるタイプなど)、ソートが2回目以降高速になるかどうかは実装に依存する、といった話がmorimorihogeさんからありました。
cardinalityもデータベースパフォーマンス調査で重要な項目という話も聞けました。cardinalityは値の種類の多さというかばらつきを表す指標で、cardinalityが低いとインデックスが効きにくくなってパフォーマンスが落ちる傾向にあるとのことでした。開発・テスト環境と本番でcardinalityが異なっていたためにクエリプランが変わってしまったことがあったそうです。リンク先を見るとヒストグラムも重要なようです。
記事では、Railsで#limit
や#offset
を使ってもActual Rowsが減らず、かえってパフォーマンスが落ちることがある例が紹介されており、気になるならwhere
で期間やidで絞り込む方がよいとのアドバイスがありました。
クエリプランやcardinalityなどデータベースチューニング周りを知りたい私のような方にはとっかかりとしてよさそうです。
シェルコマンド結果をRubyでストリーム処理する
IO.popen
をうまく使ってパイプからのストリームを待ち受けるRubyプログラムを書く方法についての記事です。これも実際にはRubyというよりはUnixのプロセスやパイプの理解に関する話のようです。
Active Recordのmany-to-many関連付けを理解する
この記事では関連付け(association)を以下に分類して解説しています。transitiveは「推移的」などと訳されることがあります。
- intransitive
- mono-transitive
- multi-transitive
なお、intransitiveではhas_and_belongs_to_many
(通称HABTM)を使っていますが、HABTM記法による関連付けはRails 3の時点で非推奨になっているとつっつき会でも指摘されていました。
3番目のmulti-transitiveの解説はかなり込み入っていますが、morimorihogeさんがホワイトボードで図解してくれましたので簡単に清書してみました。
超シンプルなRubyデコレータ
- ソース: Super simple ruby decorators(RubyFlowより)
#method_missing
でメタプログラミングをやってみました、という趣ですね。これをそのまま使うことはまずない(やったらきっと嫌がられる)と思いますが、Active Recordの黒魔術を解き明かすためにクラス名/メソッド名予想のメカニズムを知っておきたい場合は、こういうコードを一度演習として書いてみるとよさそうです。
TracePointクラスでRubyコードを追う
もしかするとあまり知られていないかもしれないTracePointクラスは、Rubyの標準ライブラリです。
この記事では、TracePointクラスを使ったデバッグのコツや、スタックトレースをGraphvizでビジュアル表示(下図)する方法などを紹介しており、洗練されたデバッグ方法として役に立ちそうです。
pluck_all gem
- ソース: pluck_all gem(RubyFlowより)
pluck_all
は配列でもハッシュでもデータを取ることができ、Rails 3でもマルチカラムでデータを取れるそうです(Rails 3のpluck
は1カラムのみ)。
クイズ「RubyかRailsか?」
- ソース: The 'Is it Ruby or Rails?'(RubyWeeklyより)
メソッドがRubyのものかRailsのものかを当てる単純なクイズです。呑みながらわいわいやるのに向いてそうですね。
Ruby 2.4の新機能
- ソース: New Features in Ruby 2.4(RubyWeeklyより)
Rubyを使う立場から新機能を紹介しています。既にTechRachoでご紹介済みの機能も多いのですが、Rubyコミッターではなく開発者側目線の記事なのでより読みやすいと思います。
いくつか目を引いたものをピックアップします。
マッチ結果から名前付きキャプチャを取り出せるようになった
pattern = /(?<first_name>John) (?<last_name>\w+)/
pattern.match('John Backus').named_captures # => { "first_name" => "John", "last_name" => "Backus" }
コマンドラインオプションをハッシュで受けられるようになった
require 'optparse'
require 'optparse/date'
require 'optparse/uri'
cli =
OptionParser.new do |options|
options.define '--from=DATE', Date
options.define '--url=ENDPOINT', URI
options.define '--names=LIST', Array
end
config = {}
args = %w[
--from 2016-02-03
--url https://blog.blockscore.com/
--names John,Daniel,Delmer
]
cli.parse(args, into: config)
config.keys # => [:from, :url, :names]
config[:from] # => #<Date: 2016-02-03 ((2457422j,0s,0n),+0s,2299161j)>
config[:url] # => #<URI::HTTPS https://blog.blockscore.com/>
config[:names] # => ["John", "Daniel", "Delmer"]
Unicodeの大文字小文字仕様に沿った処理
sentence = "\uff2a-\u039f-\uff28-\uff2e"
sentence # => "J-Ο-H-N"
sentence.downcase # => "j-ο-h-n"
sentence.downcase.capitalize # => "J-ο-h-n"
sentence.downcase.capitalize.swapcase # => "j-Ο-H-N"
Stringのnewで割り当てられるメモリサイズを:capacity
オプションで指定できるようになった
パフォーマンス向上に役立ちそうです。
シンボルの動作を改良
# Ruby 2.3 behavior:
'foo bar'.match(/^foo (\w+)$/) # => #<MatchData "foo bar" 1:"bar">
:'foo bar'.match(/^foo (\w+)$/) # => 0
# Ruby 2.4 behavior:
'foo bar'.match(/^foo (\w+)$/) # => #<MatchData "foo bar" 1:"bar">
:'foo bar'.match(/^foo (\w+)$/) # => #<MatchData "foo bar" 1:"bar">
あなたの知らないRuby 11のトリック
これも目を引いたものをいくつかピックアップしてみます。
2.いろんなlambda呼び出し
my_lambda = -> { puts 'Hello' }
my_lambda.call
my_lambda[]
my_lambda.()
my_lambda.===
7. いきなりirb
Ruby起動時に-n
オプションを付けると入力待ちモードになるとは知りませんでした。プロンプトは何も表示されませんが、入力するとちゃんと評価値が出力されます。
ruby -n -e 'p eval($_)'
8. オブジェクトのunfreeze(危険!危険!)
業務で使ったら首締められそうなコードですね。
require 'fiddle'
str = 'water'.freeze
str.frozen? # true
memory_address = str.object_id * 2
Fiddle::Pointer.new(memory_address)[1] &= ~8
str.frozen? # false
10. pryやirbのエコー出力を抑制する
末尾にセミコロン;
を打つとエコー出力されなくなります。
11. caller
メソッドで呼び出し元を知る
def foo
bar
end
def bar
puts caller
end
foo
上のようにすると以下のような出力を得られます。
-:3:in 'foo'
-:10:in '<main>'
Rubyの技101
- ソース: 101 Ruby Code Factoids(RubyWeeklyより)
Factoids(=本当は違うのにそうであるかのように報道された情報)とありますが、おそらくSEO効果を狙っているのでしょう。ここでは「裏付けなし」程度の意味ですね。明示されていませんが、Ruby 2.3を使っているようです。
数が多くて追いきれませんが、大半は割りと普通のことを書いている中にところどころ面白いものがありそうです。
その中からひとつだけ。arity
メソッドはProcやメソッドが取る引数の数を返します。
->{}.arity
# => 0
->_{}.arity
# => 1
->_,_{}.arity
# => 2
->*_{}.arity
# => -1
"".method(:upcase).arity
# => 0
String.instance_method(:upcase).arity
# => 0
ReactをRailsに置き換えてみたお
- ソース: Replacing React with Rails(RubyWeeklyより)
お題のとおりです。実は2016年の記事ですが、コメント欄もかなり賑わっています。
デバッグはputs
でやってます
- ソース: I am a puts debuggerer(RubyWeeklyより)
puts
の他にp
も使ってますが、要するにデバッガを使わないということですね。著者の@tendorloveことAaron Patterson氏は著名なRubyコミッターです。
以下のputs "#" * 90
という書き方が一同の目を引きました。「あー今まで#
キー押しっぱなしで#############...
って入力してたよー」の声が。
if $foo
puts "#" * 90
puts caller
puts "#" * 90
end
Grumpy: PythonをGoで実行する
- ソース(HackerNewsより)
HackerNewsでトップになっていました。江添さんのブログをはじめ各所で話題になっていますね。
Grumpyはインタプリタではなくコンパイラだそうです。スレッドが増えたときのパフォーマンスが目を引きますね。
Rubyコードもこんな感じでGoにコンパイルできるといいですね。
ソファー移動問題
- ソース: The moving sofa problem(HackerNewsより)
数学の問題ですが、ビジュアル表示がいいですね。
ロシアが米国民主党をクラックした手口(PDF)
レポートにはヒラリーとも民主党とも書いてありませんが、昨年の米国大統領選のタイミングなので明らかですね。米国のセキュリティ関係者の仕事の速さは見事です。
再帰的データ構造を理解する
ビジュアル表示もさることながら、説明がものすごく丁寧で個人的に好感を持ちました。
morimorihogeさんによると、ファミコン世代のようなリソースの少ないゲームプログラムでステージのデータ削減などにこの記事のテクニックが使われているかもしれないとのことでした。
fastlane: iOS/Android開発作業の自動化ツール
Rubyで書かれており、gemでもHomebrewでもインストールスクリプトでも導入できます。
Logstash: ログの変換や保存
☆6,800と人気を集めています。URLでおわかりのようにElasticのソフトウェアですね。日本語Logstash公式ページもあるのでそちらをご覧ください。
おまけ: 光子が3つのスリットを縫うように往復していることを実験で確認
諸君!
人類はついに、点sから点dに光が進むとき、赤線のような経路もたどっていることを、実験で確認することに成功したぞ。
Nature Communications誌https://t.co/TbSyRut7CA pic.twitter.com/VLLspQqGrn
— physico (@physico_physio) 2017年1月6日
今週は以上です。
関連記事
- 週刊Railsウォッチ(20161224)Float#roundの動作変更を取り消し、Rails 5.0.1/Ruby 2.4.0-rc1リリースほか
- 週刊Railsウォッチ(20161218)Ruby 2.4ではFloat#roundの動作が変わる、デフォルトのプライマリキーをBIGINTに変更ほか
- 週刊Railsウォッチ(20161209)Active Supportの非推奨メソッド廃止、RailsのjQueryへの依存を廃止ほか
- 週刊Railsウォッチ(20161125)Railsのデータベース・ベストプラクティス、SQLインジェクション解説ほか
- 週刊Railsウォッチ(20161117)DockerホスティングのHyper.sh、accepts_nested_attributes_for殺すほか
- 週刊Railsウォッチ(20161109)bundler audit gemは超おすすめ、CIAのFactbook gemほか
- 週刊Railsウォッチ(20161102)HTML 5.1正式勧告、CSS中央揃えに便利なサイトほか
- 週刊Railsウォッチ(20161027)LinuxカーネルのDirty COW脆弱性、DeviseはWikiを読めほか
- 週刊Railsウォッチ(20161019)ObjectSpaceモジュール活用法、Capybara統合、コミッターを撮影するソフト
- 週刊Railsウォッチ(20161012)RubyのHashの詳細、RethinkDBの会社が終業ほか
- 週刊Railsウォッチ(20161005)Mac OS SierraとRubyの問題、Learning Gitほか
- 週刊Railsウォッチ(20160928)constantizeの注意点、GoのGUI “gallium”登場ほか
- 週刊Railsウォッチ(20160921)クールなHTMLエディタ「Mozilla Thimble」他
- 週刊Railsウォッチ(20160913)MySQLの脆弱性ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(RSSなど)です。