配列同士でどちらかに所属する要素を取り出す

やりがちな書き方

a = [1, 2, 3]
b = [2, 3, 4]

c = (a + b).uniq #=> [1, 2, 3, 4]

これは集合で言うと和集合になる。RubyではArray同士の和集合を出力するメソッド | がある

https://docs.ruby-lang.org/ja/latest/class/Array.html#I_–7C

なので、元のコードは下記のように書き直せる

a = [1, 2, 3]
b = [2, 3, 4]

c = a | b #=> [1, 2, 3, 4]

ベンチマークしてみたところ、やはり直接和集合を求めたほうがわずかに早い

require 'benchmark'
a = [1,2,3,4,5]
b = [3,4,5,6,7]
n = 100000
Benchmark.bm(6, ">total:", ">avg:") do |x|
  t1 = x.report("|1:") { n.times { a | b } }
  t2 = x.report("|2:") { n.times { a | b } }
  t3 = x.report("|3:") { n.times { a | b } }

  total = t1 + t2 + t3
  [total, total/3]
end

Benchmark.bm(6, ">total:", ">avg:") do |x|
  t1 = x.report("uniq1:") { n.times { (a + b).uniq } }
  t2 = x.report("uniq2:") { n.times { (a + b).uniq } }
  t3 = x.report("uniq3:") { n.times { (a + b).uniq } }

  total = t1 + t2 + t3
  [total, total/3]
end
             user     system      total        real
|1:      0.120000   0.000000   0.120000 (  0.119706)
|2:      0.120000   0.010000   0.130000 (  0.119885)
|3:      0.110000   0.000000   0.110000 (  0.116694)
>total:  0.350000   0.010000   0.360000 (  0.356286)
>avg:    0.116667   0.003333   0.120000 (  0.118762)
             user     system      total        real
uniq1:   0.140000   0.000000   0.140000 (  0.141611)
uniq2:   0.140000   0.000000   0.140000 (  0.145371)
uniq3:   0.150000   0.000000   0.150000 (  0.144623)
>total:  0.430000   0.000000   0.430000 (  0.431605)
>avg:    0.143333   0.000000   0.143333 (  0.143868)

蛇足だが、共通項(積集合)を出力する & もある

a = [1, 2, 3]
b = [2, 3, 4]

c = a & b #=> [2, 3]

オブジェクト指向設計実践ガイドを読んだ

今更ながら読んだ。

書いてる内容は今の自分にとってはふんふんそうだよね。という感じ。 以下、思った点

単一責任の原則

2章でほぼすべて言いたいことは言っている感じ ここで言われている単一責任の原則はオブジェクト指向というよりプログラミングの大原則なのに、1つのクラスで色々やろうとしすぎる人が多すぎる。 本書で言う所の第4章P105あたりで TripFinder を導入するくだり。この選択をできない人は依存度が高いクラスを作りがちになると思う。

特にRailsからプログラミング始めた人は、テーブルと対になっているModelクラス以外にドメインロジックを持ったクラスを作ってはいけないと思い込んでしまう傾向があるように感じる。 こう書くとなんでもかんでも別クラスにしたがる輩が量産されそうなのでこの記事も忘れずに参照されたし。

継承

Rubyで継承を使った方がいい場面ってほとんどなくて、8割型mix-inとダックタイピングで済む話な気がしている。 というのも、僕が見てきた継承が使われているコードはほぼ全てメソッドを共有するために使われているからだ。 あとRailsで継承というと切っては離せないのがSTISTIについて話すと長くなるので割愛するが、あとで type == 'hoge' なんて書くくらいならSTIを使うべきではないと思っている。 しかし、8章にある

次のようなフレームワークを書くのは避けなければなりません。ユーザーがその振る舞いを手に入れるために、フレームワークのオブジェクトを継承しなければならないようなフレームワークです

という文章は大丈夫なのかw みんな大好きActiveなんちゃらがそうだから、みんなほげふがBaseを作って継承させるライブラリを喜々として作っている気がするw

ダックタイピング

if文でクラスをチェックしている(もしくはそれに類似する)コードは本当によく見かける。 そういうケースは大体ダックタイピングをちゃんと理解できていない。 本書を読めばダックタイピングというものがとても良く理解できると思う。

テスト

最後のテストの章が意外と大切だと思った。 基本的にテストが書きづらいクラス/メソッドは設計が間違っているパターンが多い。 最近、簡単な処理のテストを書きたいだけなのにあれこれ準備しなきゃテストできない事象に頭を悩ませている。 これは明らかにクラス間の依存度が高すぎるから引き起こされている事象だし、テストを書くことでこれらの問題に最初から気づくことができたはず。 テストがない環境で作られるものは設計がまずいケースが多い気もする。 みんな、テストちゃんと書こう

これからRubyで何か書こうとしている人って言うより、半年〜1年くらい既にRailsを使った開発PJに関わっている人とか、2年くらい運用されたRailsアプリをリファクタしなきゃいけない人とかが読むのがちょうど良い気がする。

dotfilesを一元管理するときにちょっと苦が減る方法

.vimrc、.zshrc、.gitconfigといったいわゆるドットファイル複数のマシンで使いまわすためにgithubに置くってところまでは誰もがやっているところだと思う。 ただ、それだけだといちいちローカルにコピーするとか、編集後にdotfileにコピーして…なんてめんどくさくてやらないことが多い 結果として会社のPCで登録したaliasを個人macで使おうとしたら登録してなかったり、家で試したvimプラグインを反映し忘れてててげんなりする。 というわけで最近以下のようにローカルのファイルは外部ファイル読み込みにしてしまった

# .vimrc
source ~/dotfiles/.vimrc
# .zshrc
source ~/dotfiles/.zshrc
# .gitconfig
[include]
  path = ~/dotfiles/.gitconfig

更に、aliasを登録してこれらのファイルを編集するときは常にdotfiles以下の方を編集するようにする

# .zshrc
alias vrc='vim ~/dotfiles/.vimrc'
alias zrc='vim ~/dotfiles/.zshrc'
alias gcon='vim ~/dotfiles/.gitconfig'

これで常にローカルにあるdotfilesを編集すればよく、コピーしてどうちゃらみたいなことから開放される シンボリックリンクにしてもいいけど、外部参照にしておくことでローカル固有の設定を追記できるのでこういうふうにしてる これをやっても結局は編集後にコミットしてプッシュする、とか別マシンで変更がしたらpullするという手間は残ってるけど、その辺自動にするとそれはそれでイライラする要因を生む気がするのでそこまではやってない

【Ruby】正規表現で文字列を置き換えようとしてハマった

ある文字列について、あるパターンに合致した部分を装飾して置き換えたいことがあった。

例えば、「123hoge456」を「123 + hoge + 456」みたいにhogeをマッチさせて再利用する感じ。

そのためのコードを以下のように書いたのだが思ったように動かない。

str = "123hoge456"
str.sub!(/(hoge)/, " + #{$1} + ") # => "123 +  + 456"

どうやら、$1に何も入っていない? そう思って次の行で$1を出力してみる

1    a = "123hoge456"
2    a.sub!(/(hoge)/, " + #{$1} + ") # => "123 +  + 456"
3    p $1 # => "hoge"

あれ、$1にはちゃんと入っている??
更に、実際には書いてたコードでは2回こういう処理するようになってたのに更に奇妙な挙動になってた

1    a = "123hoge456"
2    b = "123huga456"
3    a.sub!(/(hoge)/, " + #{$1} + ") # => "123 +  + 456"
4    b.sub!(/(huga)/, " + #{$1} + ") # => "123 + hoge + 456"

ここで分かった人には分かったと思うのだが、実は最初のsubの呼び出し時点ではまだ$1はnilになっているのが原因。
3行目が終わったところでは$1に"hoge"が入っているので、さっきの例では出力できたし、この例では次の4行目の引数に与えられている。
なんとなく第一引数の正規表現がすぐに処理されているように感じるけど、メソッド呼び出す時点では処理されていないってわけで。
なるほどなー

じゃ本来やりたかったことをやるにはどうすればよいかというと、以下のようにsubにブロックを渡してやると良い。

1    a = "123hoge456"
2    a.sub!(/(hoge)/){ " + #{$1} + " } # => "123 + hoge + 456"

更に言うと、そもそもブロック使うならマッチ部分を受け取れるので、

1    a = "123hoge456"
2    a.sub!(/(hoge)/){|match|  " + #{match} + " }# => "123 + hoge + 456"

これで事足りるのであった。。。

よくよくみたらリファレンスにも書かれてた。
http://docs.ruby-lang.org/ja/2.1.0/class/String.html#I_SUB

注意:

第 2 引数 replace に $1 を埋め込んでも意図した結果にはなりません。 この文字列が評価される時> 点ではまだ正規表現マッチが行われておらず、 $1 がセットされていないからです。

入門Chef soloを読んだ

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

Wordpressでなんか作ろうかと思っているのだけど、手元のVagrantで開発環境作りたいなーと思ってて、どうせならChefでインフラの構成管理してみるかってことで今更ながらChefを本格的に触ってみた。

意外とネットではわからなかったChef入門

今までもどんなもんかは大体知ってたつもりだったからネットで入門記事でも見れば使えるだろうと思って読み始める…がどれもまったくわからない。
いや、書いてあることはわかるし動くには動くんだけど用語とか概念がわからない。肝心なところの説明があっさりしていて、失礼ながらほんとに理解できてますかとか思ってしまうレベル。
おそらく紙面の都合とか無理に説明しようとすると複雑すぎてかえってわかりづらいとかだろうけど…

かといって公式ドキュメントはそれはそれは難解っていう。

このような状況で体系的にChefの説明をしていてわかりやすい本でも読みたいなってところで調べてみると候補は以下の感じ、

参考;書評「Chef活用ガイド」と「Chef実践入門」について - さよならインターネット

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

Chef活用ガイド コードではじめる構成管理

Chef活用ガイド コードではじめる構成管理

この二冊は圧倒的知名度だし、このどちらかにしようと最初は考えてた。
Kindleで読みたいなってところから前者よりだったんだけど、レビューによると長くて厚いリファレンス本臭がするしなぁと迷っていたんだけど、@naoya_itoさんの「入門Chef Solo」がボリューム的にも内容的にも価格的にもベストじゃね?とか思って勢いで買った。

恐縮ながら書評

結果的にはベストチョイスだった。
凄くわかりやすいしボリュームの割に網羅的。 目次を見れば一目瞭然。

第1章 Chefとは何かを知りたい ─ Chef Overview

第2章 Chef Soloをインストールして試したい ─ Hello Chef!

第3章 nginxをChef Soloで立ち上げたい

第4章 Chef Soloの試験環境を3分で用意する ─ Vagrant

第5章 リモートからchef-soloを実行する ─ knife-solo

第6章 レシピを作って実行する流れをおさらいしたい

第7章 サードパーティのChef クックブックを使いたい

第8章 代表的なレシピのサンプルを見たい ─ td-agent のレシピを読む

第9章 パッケージをインストールする ─ Package

第10章 サービスを起動したい ─ ServiceとNotification

第11章 テンプレートから設定ファイルを配置したい ─ Template

第12章 ファイルやディレクトリを扱いたい ─ Cookbook File, Directory

第13章 ユーザーを作成したい ─ User, Group

第14章 gitレポジトリからファイルを取ってくる ─ Git

第15章 任意のシェルスクリプトを実行したい ─ Execute, Script

第16章 その他のResource

第17章 レシピ落ち穂拾い ─ run_list, ファイル分け, include_recipe

第18章 Resourceを自分で定義したい ─ Definition

第19章 AttributeとData Bag

第20章 ノードを役割ごとにグルーピングして管理したい ─ Role

第21章 サードパーティのクックブックをBundler 風に管理したい ─ Berkshelf

第22章 Chef Serverの様子を知りたい ─ 概要からセットアップまで

第23章 どこまでをChefでやるべきか

一見「長っ!」って感じだけどこれだけの内容で百数十ページでさらさら読めるのでそこは安心していただきたい。

これをひと通り読めば公式のcookbookが読めるようになるからそれの利用とか編集もできるようになる(読む前は正直意味不明だったw)
あと読んでて印象深かったのは、下記の部分

このスナップショット機能をはじめとする AWS の各種サービス利用すると、そうでは ない場合に比較して運用が非常に楽になりました。それだけでも十分に楽だったので、こ れ以上の自動化は必要無いかな......なんて思っていました。 ところがスナップショットを多数とって管理しているうちに、どのスナップショットが どういった状態で保存されたものなのかを管理するのが大変になってきました。

これはまさに僕も思っていて、AWSのAMIみたいなスナップショットがあれば別にいいんじゃね?って最初は思ってたんだけど、古いスナップショットとか結局何が今と違うのかわからなくなるんだよね。

すべての状態はコードに記 載されているので記憶に頼る必要はありませんし、履歴は git でバージョン管理されてい ます。インスタンスを立ち上げたらとりあえずレシピを適用しておけば、思ったとおりの 状態にノードが収束してくれます。こんなに良いことはないですね。

Chef使うとここが解消されるってね。フンフンなるほどなーという感じだった。インフラをコードで扱えることの真髄だね。
利点はわかってるつもりだったけど改めて再認識。

価格も手頃だし、マジでおすすめします。

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

達人出版会ならpdfでも買えます。

補足1

書籍の中で、nginxをインストールするためにepelを追加する場面があるのだけど、

{
   "run_list" : [
     "yum::epel"
   ]
}

実は、この書籍が発行された後にyumのcookbookがバージョンアップしていて、yumのrecipeからepelというのはなくなっている。
なのでこのまま実行すると、

Chef::Exceptions::RecipeNotFound
--------------------------------
could not find recipe epel for cookbook yum

こんな感じで怒られる。
対応方法は2つある。

  1. yum-epelを使う
    これを落としてきて使う。コマンド的にはこんな感じ

  $ knife cookbook site install yum-epel
  $ vi nodes/hoge.json

  {
   "run_list" : [
       "yum-epel",
       "nginx"
    ]
  }  

2. yumyum_repositoryというResourceを使って自分で定義する
自分で書いたnginxのrecipeを以下のように追記して、nodeの方はいじらない。
詳しくはyumのcookbookのREADME.mdに例が書いてある。

yum_repository 'epel' do
  description 'Extra Packages for Enterprise Linux'
  mirrorlist 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch'
  gpgkey 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'
  action :create
end

更に補足

epelからnginx入れるとバージョンが1.0.15になる。
最新のStableバージョンが1.6.1なのでだいぶレガシーである…
これを回避して新しいバージョンを入れる方法は別エントリで書きます。

Goを始めました

最近の新言語ラッシュの中でもイケてそうなのはGoかなとか思って始めて見た。

Goの特徴

箇条書きにしてみる

  • コンパイルと動作が早い(らしい)
  • 初期化時に型推論があるけど、基本、型は厳密
  • クラスない
  • structとポインタ使ってひとまとまりのデータを扱うことはできる
  • ポインタあるけどポインタ演算はない
  • ゴルーチンでびっくりするほど簡単に関数の並列実行ができる

チュートリアル「Tour of Go」

Tour of Goっていうチュートリアルがあって、これをやれば基本的なことはすべてわかる。
ただし、すげー長い

チュートリアルやってみて

書きやすくなったCって印象を受けた。
実際僕が今まで触ったことある言語の中では圧倒的にCが近い。

ポインタ書いたことない人は結局ポインタで躓くんじゃないかと予想。
後は普段Javaの人はクラスない、当然継承もない、インターフェイスがあるにはあるけどimplementsを宣言しなくていいとか色々やりずらそう(?)

自分の回答はgithub置いといた
https://github.com/syguer/tour-of-go.git ググればもっといい答えが出てくると思われる

とりあえずwebアプリ作るとこまではやってみようと思う

基礎からわかる Go言語

基礎からわかる Go言語

Go言語プログラミング入門on Google App Engine

Go言語プログラミング入門on Google App Engine

RubyでTrelloのアクセストークンを取得する方法

TrelloのAPI使ってなんかやろうと思ったんだけど、アクセストークンを取得する方法についての日本語情報が見当たらなかったので紹介する

Trelloについて

今更説明するまでもないが、Trelloはカンバン的な形式でタスクを管理したりできるサービス
簡単に使えるので仕事でも使ってるし個人でも結構使ってる

https://trello.com/

アクセストークンを取得する

Trelloも最近のサービスの例に漏れずOAuthでトークンを取得してAPIを使うのでアクセストークンを取得する  

コードはこんな感じ

consumerKeyとconsumerSecretはTrelloにログインして下記URLにアクセスすると表示される

https://trello.com/1/appKey/generate

Twitterのアクセストークン取得に関する情報を見るとOAuth::Consumer#newの第三引数にはsiteしか指定してないけど、trelloの場合はこんな感じで指定しないとダメらしい(OAuthプロバイダの仕様の差(?)

ともあれこれを実行するとURLがでてくるのでそれにアクセスすると、承認画面に飛ぶ

f:id:syguer:20140724233708p:plain

承認するとpinが発行されるので、これをコンソールに戻って入力

f:id:syguer:20140724234019p:plain

pinを入力するとアクセストークンを出力される

$ ruby get_access_token.rb
"https://trello.com/1/OAuthAuthorizeToken?oauth_token=1781bb9f93231cb0068c678**********"
Input your pin code => "ここにPINを入力"
token =>  2d9cea749bbca58a45a4496e4a6007b311dc1306ba893a5854ef3e*********
secret => ba0ac713434433f02fda35**********

これを使えばTrelloのAPIを使える。APIの使い方はまた次のエントリで