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

週刊Railsウォッチ(20170110)ReactをRailsに置き換える、Ruby 2.4の新機能ほか

あけましておめでとうございます、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デコレータ

#method_missingでメタプログラミングをやってみました、という趣ですね。これをそのまま使うことはまずない(やったらきっと嫌がられる)と思いますが、Active Recordの黒魔術を解き明かすためにクラス名/メソッド名予想のメカニズムを知っておきたい場合は、こういうコードを一度演習として書いてみるとよさそうです。

TracePointクラスでRubyコードを追う

もしかするとあまり知られていないかもしれないTracePointクラスは、Rubyの標準ライブラリです。

この記事では、TracePointクラスを使ったデバッグのコツや、スタックトレースをGraphvizでビジュアル表示(下図)する方法などを紹介しており、洗練されたデバッグ方法として役に立ちそうです。


How To Spy on Your Ruby Methodsより

pluck_all gem

pluck_allは配列でもハッシュでもデータを取ることができ、Rails 3でもマルチカラムでデータを取れるそうです(Rails 3のpluckは1カラムのみ)。

クイズ「RubyかRailsか?」

メソッドがRubyのものかRailsのものかを当てる単純なクイズです。呑みながらわいわいやるのに向いてそうですね。


Rails Hurtsより

Ruby 2.4の新機能

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

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に置き換えてみたお

お題のとおりです。実は2016年の記事ですが、コメント欄もかなり賑わっています。

デバッグはputsでやってます

putsの他にpも使ってますが、要するにデバッガを使わないということですね。著者の@tendorloveことAaron Patterson氏は著名なRubyコミッターです。

以下のputs "#" * 90という書き方が一同の目を引きました。「あー今まで#キー押しっぱなしで#############...って入力してたよー」の声が。

if $foo
  puts "#" * 90
  puts caller
  puts "#" * 90
end

Grumpy: PythonをGoで実行する

HackerNewsでトップになっていました。江添さんのブログをはじめ各所で話題になっていますね。

Grumpyはインタプリタではなくコンパイラだそうです。スレッドが増えたときのパフォーマンスが目を引きますね。


Open Source Blogより

Rubyコードもこんな感じでGoにコンパイルできるといいですね。

ソファー移動問題

数学の問題ですが、ビジュアル表示がいいですね。


Dan Romik's home pageより

ロシアが米国民主党をクラックした手口(PDF)

レポートにはヒラリーとも民主党とも書いてありませんが、昨年の米国大統領選のタイミングなので明らかですね。米国のセキュリティ関係者の仕事の速さは見事です。

再帰的データ構造を理解する

ビジュアル表示もさることながら、説明がものすごく丁寧で個人的に好感を持ちました。

morimorihogeさんによると、ファミコン世代のようなリソースの少ないゲームプログラムでステージのデータ削減などにこの記事のテクニックが使われているかもしれないとのことでした。

fastlane: iOS/Android開発作業の自動化ツール

Rubyで書かれており、gemでもHomebrewでもインストールスクリプトでも導入できます。

Logstash: ログの変換や保存

☆6,800と人気を集めています。URLでおわかりのようにElasticのソフトウェアですね。日本語Logstash公式ページもあるのでそちらをご覧ください。

おまけ: 光子が3つのスリットを縫うように往復していることを実験で確認

今週は以上です。

関連記事

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

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

RubyFlow

160928_1638_XvIP4h

Ruby Weekly

Hacker News

160928_1654_q6srdR

Github Trending

160928_1701_Q9dJIU


CONTACT

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