すがブロ

sugamasaoのhatenablogだよ

divergence_meterというgemを作った - Webアプリエンジニア養成読本 Advent Calendar 2014 24日目

Webアプリエンジニア養成読本 Advent Calendar 2014 - Qiita の24日目です。12/24の23:40の時点で書き始めているので許してニャン

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

このアドベントカレンダーGemライブラリ作ってこ! - すがブロ という話を書きました。 その続きというわけではありませんが、少し前にGemライブラリを作成したのでその話をしたいと思います。

何を作ったのか

レーベンシュタイン距離 - Wikipedia という文字同士の編集距離を調べるアルゴリズムを実装したのでした。 例えば、aaaaab は1文字変更すると同じ文字列を作成できるので、編集距離が1ということになり、 比較的似ている文字列である というのがわかります。

ついでに、編集距離を調べるだけではなく、調べたい単語と、辞書データ(単語群)を引数で渡すと、単語に最も近い辞書データの単語を探してくるという「もしかして?」機能も作ってみました。

$ gem i divergence_meter --no-document
Fetching: divergence_meter-1.0.1.gem (100%)
Successfully installed divergence_meter-1.0.1
1 gem installed
$ pry
[1] pry(main)> require 'divergence_meter'
=> true
[2] pry(main)> DivergenceMeter.もしかして('__sand__', %w(send __send__ hoge))
=> "__send__"

実装自体は上記のWikipediaに乗っている擬似コードRubyに読み替えるだけなので大して難しくありません。それどころか、実装した後で気がついたのですが

編集距離が近いメソッドを勝手に呼ぶ - hitode909の日記

とか

編集距離 (Levenshtein Distance) - naoyaのはてなダイアリー

とかで語られていて、もう何周遅れのネタだったんだ、という感じです。テストケースの材料としていくらか参考にさせていただきました。

あ、ちなみにこのアルゴリズムを実装した目的は、この文章のような長文の文字列から誤字脱字を見つけられないかなと思って作ってみたのでした。

すでにあるもの作ってどうするの問題

自分にとっては、このアルゴリズムを実装するのは初めての経験だったので良いのです。いわゆる車輪の再発明ってヤツですが、作る上で学びがあるなら良いじゃないか〜という感じですね。あと、個人的なニーズとして、Gemライブラリになっていると都合が良かったというのもあります*1

すでにあるものを作ってどうするのかという葛藤、あるにはありますが、その分野で一旗揚げるような野心がある人は別として、自分の経験のために作っても良いと思いますのでカジュアルに作ってみるのが良いのかな、と思います。

ちなみにGemライブラリの名前の由来は

編集距離を世界線変動率*2と置き換えてみたら面白いかなーという思った次第です。

書かなくてはならない宣伝

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

この本を読んだあと、何かコードを書いてみたいけどイマイチ書くものが思いつかないよ! という方は、上記のレーベンシュタイン距離のような簡単なアルゴリズムを自分でRubyのコードに翻訳してみる、というのをやってみると意外と面白いかもしれませんね。

enjoy!

*1:当初GitHubにだけ公開してたのですが、ちょっと事情があってRubyGemsにもアップしました

*2:シュタインズゲートでググってみてください

Webアプリエンジニア養成読本ではあまり説明できなかったRubyの便利なヤーツ

Webアプリエンジニア養成読本 Advent Calendar 2014 - Qiita の21日目です。ガチで書くことがなくなってきました!恐縮です。

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

擬似変数たち

本書ではあまり触れていませんでしたが、Rubyでは擬似変数と呼ばれる、変数のような値がいくつか存在します。例えば、truefalseもそれに該当します。

それ以外で面白いものとして、__FILE____LINE__等があります。これらは実行した時点でのファイルのパスや行数を取得することができます。

ちなみに、Ruby 2.0.0からは__dir__ というメソッド(これは特殊変数ではないのだった)も追加されていて、これを使うと File.dirname(__FILE__) 相当……つまり、該当のファイルが格納されているディレクトリ部分を取得できます。

こんな感じのコードで試してみましょう。

cat hoge.rb
puts "start:hoge"
puts __FILE__
puts __LINE__
puts __dir__
puts "end:hoge"

これを実行してみると

$ ruby hoge.rb
start:hoge
hoge.rb
3
/private/tmp
end:hoge

こんな感じで取得できます。

詳しくは 変数と定数 を見てください。

その他によく使うもの

擬似変数のようなくくりではありませんが、例えばコマンドライン引数を扱うための値として、ARGVやARGFがあります。

ARGV.each do |arg|
  puts arg
end

これを引数付きで実行するとこんな感じになります。

$ ruby sample.rb foo bar baz
foo
bar
baz

ARGFを使うと、引数の値をファイルパスとみなして、内容を読み込むことができます。詳しくは constant Object::ARGVobject ARGF を参照してください。

ここらへんのオブジェクトなどを利用できるようになると、ちょっとしたコマンドラインツールを作るときに役に立ちますね。

おまけ

Rubyではputs等のレシーバを指定しないメソッドはおおよそKernelに定義されているものです。 module Kernel あたりを見ると、例えば exitsleep 等のメソッドが定義されているのがわかります。ちょっとしたコードを書くときに知っておくと便利なヤーツがあるので、ここらへんのメソッド・特殊変数は抑えておくと良いでしょう。

書かなくてはいけない宣伝

今回のエントリで書いたようなことは書けていませんが、書店などで見つけたらぜひ立ち読みでもしてみて、あわよくば購入してみてくださいね。

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

enjoy!

Rubyでアプリケーション以外のコードを書く

Webアプリエンジニア養成読本 Advent Calendar 2014 - Qiita の19日目です。そろそろ書くことなくなってきましたね。

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

本書を読んだあなたが

もし、Rubyを気に入ってくれているのだけど、直近のプロジェクトでRubyは使わないんだなーという場合に役立つかもしれません。

プロビジョニングツールを使ってみよう

最近流行ってますよね。DevOpsってヤツ。デブオプス。Ruby製のツールとしてはChefが一世を風靡したことは記憶にあたらしいところです。

しかし、この世はChef疲れを起こす人々であふれています*1。本稿ではもう少しお手軽に使えるツールとして ryotarai/itamae · GitHub について説明していきます。

ChefやitamaeはDSLで設定を書いていくスタイルですが、Rubyの構文が使えますので、本書で手に入れた知識が役に立つ時です!

itamaeをインストールする

前提となる環境は以下のとおりです

  • OSX Yosemite
  • Homebrewがインストールされている
  • Bundlerがインストールされている

まずはGemfileの生成を行います。

$ bundle init
Writing new Gemfile to /private/tmp/itamae_sample/Gemfile

おもむろにGemfileを編集します。

# A sample Gemfile
source "https://rubygems.org"

gem "itamae"

Gemfileの編集を行ったら bundle install を実行してインストールします。

レシピファイルを作成します

ここでは、自分のOSXの環境構築でインストールするお決まりのツールをitamaeでインストールするようにしてみましょう*2

recipe.rbというファイルを作成し、下記の内容を記述してみましょう。golangをパッケージングシステムを使ってインストールするための内容です。

packageは実行されるOSによって最適なパッケージシステムが選択されます。つまり、OSX上で実行する場合はHomebrewが選択されます。

package 'go'

これだけ記述したら、itamaeを実行してみます。

itamaeにはlocalモードとsshモードがありますが、今回はローカルに対して実行したいのでlocalという引数を使っています。そして、最後に作成したレシピファイルのパスを指定してあげます。

$ bundle exec itamae local recipe.rb
 INFO : Starting Itamae...
 INFO : Recipe: /private/tmp/itamae_sample/recipe.rb
 INFO :    package[go]
 INFO :       action: install

そうすると、goパッケージがインストールされました。

もうちょっとRubyっぽさを……

これだけで「ドヤ?Rubyで掛けて便利やろ?」などと言われても「ハァ、Rubyっすねぇ」というしかないと思うので、もうちょっとRubyっぽい感じでかける例にしてみましょう。例えば、goだけではなく、treeもインストールしたい!!という時、愚直に書くとこんな感じになるでしょう。

package 'go'
package 'tree'

しかしここはRubyの世界。このようにも書けます。

%w(go tree).each do |name|
  package name
end

goとtreeをRubyの構文で配列にしてeachで繰り返すようにしました。

$ bundle exec itamae local recipe2.rb
 INFO : Starting Itamae...
 INFO : Recipe: /private/tmp/itamae_sample/recipe2.rb
 INFO :    package[go]
 INFO :       action: install
 INFO :    package[tree]
 INFO :       action: install

これを実行すると、複数のファイルが読み込まれているのがわかりますね。

itamae自体は設定ファイルをjsonで外出しにする機構もあるので、あまりこういう使い方はしないかもしれませんが、用途に応じて、簡素に書ける方法を考えていくのが良いですね。

雑なまとめ

  • itamaeは便利
  • itamaeはRubyが書けるので便利
  • itamaeはChefと違って少ない設定でかけるので、ローカルの環境構築とかに便利
  • itamaeの詳細はGitHubを見よう!(当たり前ですがpackage以外にもgitとか色々あります!)
  • itamae自体はバックエンドに serverspec/specinfra · GitHub を使っているため、RedHatBSDでも動きます*3
    • Serverspecと同じものを使っているということですね
  • すぐにRubyを触れない状態でも、Rubyを使う用途はアプリケーション以外にもあるので、そういうところから狙うと良いかもしれません

書かなくてはならない宣伝

itamaeの設定を書くくらいであれば、Rubyを簡単に知っていれば十分なので、↓のRubyの解説を読んだくらいでもなんとかできるんじゃないかなーと思います!!

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

次のアドベントカレンダーおじさんは @koemu さんです。

enjoy!

*1:主に僕のことですが、、、

*2:実際のところ、このマシンは環境構築済みなのであまり恩恵はないですが……

*3:僕は確認してませんが、Windowsでもワンチャンありそう

写経のススメ

Webアプリエンジニア養成読本 Advent Calendar 2014 - Qiita の15日です。

本を読み進めるとき

本だけではなく、ステップバイステップで進めていくものなら該当すると思いますが、イマイチ勘所がわからない状態で何かを学ぶとき、おおよそ以下のようなステップを踏むと思います。

  • 書いてある事を打ち込んで手元で動かす
  • 自分の興味や望んだ挙動になるようにちょっと変更する

言われるがままに写した部分で「はぁ?なんでここでこんなこと書いてんの?」とか、「ちょっと挙動変えたらわけわからんくなった、、、」とかって結構あると思うんですよね。ていうかぼくは結構あるんですよね……。

そんな時は、これがおすすめです*1

たとえば、上記の写経ログをGitHubにあげている状態で本の内容でわからない部分を質問すると、質問者に自分が困っている状態のコンテキストがある程度伝わると思うので良い回答が得られるんじゃないかなと思います。

あと、GitHubにあげておくと草が生えるのでぱっと見で「オッ、この人コード書いてるナ!」みたいな印象は得やすいような気がしますね。手を動かしてナンボなところはあるので、それをPCの肥やしにするよりは良いかなーと思います。

ところで、本書Webアプリエンジニア養成読本のプログラミング言語の部分は、写経していけるようなステップバイステップな構成にしています*2。gitの勉強も兼ねて、写経してみてはいかがでしょうか?

enjoy!

しなくてはならない宣伝

そろそろ、本の内容とあんまり関係がなくなってきましたね。キビシイ!

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

*1:今でも色あせぬ名言、すばらしいです……

*2:筆者たちはそういうつもりで書いてます

Gemライブラリ作ってこ!

これはWebアプリエンジニア養成読本 Advent Calendar 2014 - Qiitaの10日目の記事です。下書きに保存のまま一日寝かせてしまいました……。

Gemライブラリを作ってみよう

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

この本の中でもSinatraをはじめ、様々なGemライブラリをインストールしています。Gemライブラリ、便利で良いですよね。いやー賢い人が作ってくれた叡智のおかげで我々のような下々の者は楽ができます。すばらしい!

さて、ここでタイトルに戻りますが、いきなりライブラリを作ってみようとか言われても「え、ちょっといきなりは……」ってなりますよね。そうですよね。

一般的に、「Gemライブラリとしてリリースした」というと http://rubygems.org/ に公開している状態を指しますが、ここではもうちょっとお手軽な方法を紹介します。

BundlerとGitHub

BundlerでGemライブラリをインストールする場合、基本的にはrubygems.orgを参照しますが、gemの指定部分にGitHub*1のURLを指定することができます*2

この指定を利用することで、RubyGemsで公開せずにGitHubに公開しておくだけでBundlerでGemライブラリとしてインストールし、利用できるようになります。

RubyGemsにgemライブラリとして全世界へ公開や!というのよりは、GitHubの自分のリポジトリに公開しておくだけの方が気が楽だと思いますので、最初の一歩としてこちらを試してみると良いでしょう。

どうやってやるの

Bundlerがインストールされているのを前提としますが、Bundlerを使うと、Gemライブラリのひな形が簡単に作れます。

$ bundle gem super_cool_gem

このようにbundle gemというサブコマンドで、Gemライブラリのひな形を作成することができます。

あとは好きな様にライブラリを書き、コミットし、自分のGitHubへpushすればそれでオーケーです。

ちなみに、Rakeタスクがいくつか登録されており、rake releaseとするとRubyGemsにリリースされます(ワオ、親切〜)。

Bundlerからの指定方法

GitHubリポジトリにsuper_coll_gemというライブラリをpushしたとしましょう。

super_cool_webappというクールなWebアプリケーションを作る際にsuper_cool_gemを使いたい。そんな時はBundlerが使用するGemfileファイルに以下のように書きます。

source "https://rubygems.org"

gem 'super_cool_gem', git: 'https://github.com/sugamasao/super_cool_gem.git'
    :

このように、gem名の後にハッシュ形式でgitというkeyとリポジトリを指定します(super_cool_gemは存在しないのでインストールできません)。

追記:GitHubの場合、以下のようにgithubというkeyを使うことでもうちょっと簡単に指定ができました!!(ありがとうございます)

ちなみにこの指定方法、まだRubyGemsに上がっていない最新版ライブラリを使いたい場合によく利用されます(ブランチの指定もできるので、本流に取り込まれていない特定のブランチを指定する、ということも可能です)。

もっとGemの作り方知りたいってばよ!

そのような場合、ぜひこの書籍をご利用いただければと思います。

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby | Gihyo Digital Publishing

次のアドベントカレンダー執筆者はこえむさんで、 手順で議論白熱? | こえむの編集後記 です。

こちらからは以上です

*1:正確にはGitHubではなくgitリポジトリであればオッケー

*2:なお、gemコマンド単体ではこのような方法はできませんが、似たようなことをできるツールもあります

では、Sinatraの使いどころとは一体

Webアプリエンジニア養成読本 Advent Calendar 2014 - Qiita

これの6日目です。すでに7日になってしまい大変恐縮です。

ところで、この書籍(みなさん100万回読んでいると思うので蛇足だと思っていますが!!)では、Sinatraを使って簡単なWebアプリケーションを作成しています。ちなみに、書籍で作成するWebアプリケーションのソースコードsugamasao/Shiori · GitHub にあります。

なぜSinatraなのか

Sinatra自体は非常に手軽で学習コストが低いこと、その上で一歩ずつ組み立てていくのでWebアプリケーションとは?みたいな題材だとかなり良いと思っているのですよね。Webアプリケーションに必要な構成要素と必要な要素の説明がしやすいんです。

とは言え、カッチリつくろうと思うとファイル数が増えても破綻しないようなディレクトリ構成等を始め、いくつか考えていく必要がでてきます。

SinatraベースのWebフレームワーク

Sinatraベースで、ModelやViewがセット*1になっていて、ディレクトリ構成等がある程度整備されているWebフレームワークとしてPadorinoがあります。

Padrino で素敵なウェブ開発を - Padrino Ruby Web Framework

これを使うと、Sinatraの使い勝手を維持しつつ、ある程度の整備されたレールに乗ることができます。例えば、ジェネレータやコマンドラインベースで実行できるようなrunner等が用意されていて、必須ではないけどあると助かるなぁという部分が補えて良いと思います。

いやしかし……

そう、ここまでやるならRailsで良いのでは。みなさんも思うでしょう。私もそう思います*2。 もちろん、Padrinoにも良さはありますし、自分でコントロールできる幅が広いので、こちらを好む人もいらっしゃるとは思います。ただ、漠然と選択するというよりは、「Padrinoが使いたいんだ!」という気持ちで使って行ったほうが良いのかな、と思います。

では、Sinatraの使いどころとは一体

あまり凝ったことはせず、なんなら1ファイルでも完結するくらい単純なWebアプリケーションを使う場合はとても良いでしょう。例えば、Twitterのとあるキーワードを集めたクローラーを作ったとして、それを閲覧するためのView用のアプリケーションとかですかね。

実際、本書で書いているWebアプリケーションはほぼCRUD操作をする程度のもので、雑に書いてしまえば1ファイルにおさめてしまっても良いくらいの規模ですしね。

まずはお手軽なSinatraを使ってWebアプリケーションを書いて、複雑になって行きそうな規模になったら、その時はRailsやPadrinoを検討してみるのが良いでしょう*3。そうすることで、Sinatraを使う上で検討してきたこと、自分が選んだ選択肢に対して、別のフレームワークがどのような選択をしているのかがわかって情報の洪水に溺れなくて済むのかな、なんて思います。

しなくてはならない宣伝

僕の担当した部分としては、簡単なRubyでのプログラムの書き方からSinatraでのWebアプリケーションまで書いています。どんなもんか興味がある人は書店で立ち読みでもしてみてください*4

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

しなくてはならない宣伝2

もっとRubyにいて知りてーんだよって人にはこちらをおすすめします。

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

あるいは、Railsについて知りたい方はこちら……と言いたいところですが、初めてRailsを触る人向けではないので、その点だけご注意ください。

パーフェクト Ruby on Rails

パーフェクト Ruby on Rails

*1:これらのライブラリはデフォルトで用意されているもの以外に変更することが可能だ

*2:いくら変化が早いと言われてもユーザ数が多い分、情報のでかたに違いがあります

*3:そういう呑気なものが許されるのであれば、、、

*4:気に入ったら買ってね!!

Markdownで執筆をした話

Webアプリエンジニア養成読本 Advent Calendar 2014 - Qiita

これの1日目です。

Webアプリエンジニア養成読本は みんなで「Webアプリエンジニア養成読本」を書きました! - ゆーすけべー日記 でも書いてある通り、Github上のMarkdownを使って執筆しました。

ここでは、パーフェクトRuby / パーフェクトRuby on Railsを執筆する際はRe:VIEW*1を使っていた、という経験を踏まえた上での所感を書きます。

圧倒的メリット

閲覧がメチャクチャ楽という点に尽きます。とにかく、Github上で原稿を見るというのが非常に楽だし、マークアップも僕らの大好きなGithubフレーバーです。

ちょっとしたデメリット

致命的ではないけれど、以下の点はちょっと気をつける必要があります。

  • 注釈やコードブロックなど、書籍用のマークアップはないので表現力に限界があります。そこら辺は編集者さんとの協調を得ながらやっていく必要があります
  • 各章への参照*2やリスト番号*3等をいい感じにしてくれるような機構はないため、場合によってはそういうのを手動で頑張る必要があるかもしれない
    • 本書ではそういうのはほとんどなかった

所感

各章が数万文字、かつ各章ごとにほとんど関連がないようなものだと、MarkdownをpushするあるいはMarkdwonエディタで参照すればすぐに完成形が見れるというのはこの上もないメリットです。

執筆当時はなかなか良いMarkdownエディタに巡りあえず苦労しました*4。Markdあたりを使ってましたが、いまならAtomとかが良いんでしょうね、たぶん……。

はい

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

よろしくお願いいたします

*1:https://github.com/kmuto/review

*2:X章 xxxxみたいなヤツ

*3:リスト 2.10みたいなヤツ

*4:Mowとかでは文字数が多すぎてまったく役に立たない