0

DSLでコマンドライン引数をparseできるargs_parserをアップデートした

まずgithub pagesでサイトを作った。

args_parser for Ruby
くわしくは上を見ればわかる。


アップデート内容

コマンドライン引数をparseした後に、validationやfilterをかけれるようになった。
parser側で入力値がチェックできるので、アプリ側でめんどうくさい処理をしなくて済む。

parseスタイルが増えた。
% rackup config.ru --port 5000 --env development
のような–key valueの他に、
% gem install twitter --version=3.7.0
みたいなイコールでつなぐスタイルも選択できる。
自分でスタイルを追加する事もできるようになってる。

順に解説する。

Validator / Filter

filterとvalidatorを追加した。こう書く。

require 'args_parser'
parser = ArgsParser.parse ARGV do
arg :url, 'URL', :alias => :u, :default => "http://shokai.org"
arg :help, 'show help', :alias => :h

filter :url do |v|
v.to_s.strip
end

validate :url, "invalid URL" do |v|
v =~ /^https?:\/\/.+$/
end
end
parse後にvalidateブロックが走って引数がチェックされる。
上の例だと引数 –url が正規表現に合わない時にエラーを起こす。


filterは、文字列を小文字にするとか、小数だったら整数に丸めるみたいな下準備に使う。
validateとfilterは何個でも書ける。


validator内のエラーはデフォルトでは
Error: invalid URL (--url hasadfttp://shokai.org)
がSTDERRに表示されて、exit 1される。


これはon_validate_error や on_filter_error を書いておけば横取りできる。exit 1されたくない時にどうぞ。

require 'args_parser'
parser = ArgsParser.parse ARGV do
arg :url, 'URL', :alias => :u, :default => "http://shokai.org"
arg :help, 'show help', :alias => :h

filter :url do |v|
v.to_s.strip
end

on_filter_error do |err, name, value|
STDERR.puts "filter error : #{err.class} #{name}=#{value}"
end

validate :url, "invalid URL" do |v|
v =~ /^https?:\/\/.+$/
end

on_validate_error do |err, name, value|
STDERR.puts "validate error : #{err.class} #{name}=#{value}"
end
end

横取り結果
validate error : ArgsParser::ValidationError url=hasadfttp://shokai.org


Style

ArgsParser#parseを呼び出す部分、ブロックしか渡さないと:defaultのstyleが使われる。

parser = ArgsParser.parse ARGV do
しかしコレだとハイフンが頭に付く文字列を引数として渡せない(負の数とか)
そういう時は別のスタイルを選べる。

:style => :equalを渡すとスタイルが変わる。

parser = ArgsParser.parse ARGV, :style => :equal do

2種類のスタイルは
https://github.com/shokai/args_parser/tree/master/lib/args_parser/styles
に入っている。

自分でスタイルを作るときは、parse_style_スタイル名(argv)を定義したArgsParser::Parserを読み込んでからArgsParser#parseを呼べばいい。

0

Rubyで文字列のレーベンシュタイン距離を計算する

文字列同士がどれだけ似ているかを計算できると便利。
例えば “uri” と “url” の距離は1というふうに計算できるので、名前を間違えた時の候補のサジェストとかに使える。
編集距離とかでググるとみんながんばってRubyで計算してるけど、levenshteinというgemを使ったら簡単だった。

gem install levenshtein

require 'rubygems'
require 'levenshtein'

p Levenshtein.distance("erik", "veenstra")
p Levenshtein.distance("shokai", "shokai")
p Levenshtein.distance("ahokai", "shokai")
p Levenshtein.distance("shokai", "ahokai")
p Levenshtein.normalized_distance("shokai", "ahokai")
p Levenshtein.normalized_distance("mmm", "uiasdfasdfasdfjsklfjasdkljalskdjflk")

7
0
1
1
0.16666666666666666
1.0

0

自動で日記書くようにした

http://shokai-log.tumblr.com


こういうのを毎日自動で書く。何していたかなんとなくわかって良い。
2012年08月11日 01時00分 @sho-virtualbox – 橋本障害

gitはadd 5回、commit 5回、pull 4回、push 4回、checkout 3回、tag 3回、mv 2回、clone 2回、reset 2回、init 1回使った
git 72回、node 55回、ls 51回、whereami 42回、cd 16回実行しました
HDD0.266GB使った。残り10.214GB空いてる



しくみ
https://github.com/shokai/autodiary これをcrontabで1日1回実行するだけ。
zshのhistoryを24時間分読んでtumblrに投稿する。
ruby autodiary.rb –run で動く。


元ネタ:Pitecanサーバ日記

0

Mac/LinuxのWiFiで位置情報を取得

wifi_locationというrubygemを作った。Mac (Lion, Mountain Lion)と Ubuntu 12.04で動く。

gem install wifi_location
whereami --help
whereami --dump
whereamiというコマンドが付属してるので、これを使うと
{"towers":[{"bssid":"20:f3:a3:8c:66:ab","signal":-72},{"bssid":"00:0a:79:a5:7c:16","signal":-80},{"bssid":"1c:b1:7f:11:f8:c2","signal":-82},{"bssid":"20:f3:a3:32:58:f7","signal":-91},{"bssid":"の","signal":0},{"bssid":"00:24:a5:b8:90:e7","signal":-80},{"bssid":"10:c6:1f:ec:f8:49","signal":-56}],"location":{"latitude":35.640688,"longitude":139.6941365,"address":{"country":"日本","country_code":"JP","region":"東京都","city":"目黒区","street":"1丁目","street_number":"1"},"accuracy":40.0}}
こういうのが出てくる。
WiFiアクセスポイントのBSSID(Macアドレス)と電波強度を http://www.google.com/loc/json に送ると位置情報が得られる。かなり精度高い。


参考


これをRubyで実装するとこうなる


インストール

gem install wifi_location


Rubyから使う

#!/usr/bin/env ruby
require 'rubygems'
require 'wifi_location'
loc = WiFiLocation.location
puts "#{loc['latitude']}, #{loc['longitude']}"
p loc
WiFiLocation.locationが返すhashに、緯度経度住所番地国名などなどが入っている。


whereami

gem installするとwhereamiコマンドが使える。
whereami –map でgooglemapが開く
whereami –dump で全部表示
引数なしで、緯度経度のみ表示する。


オフラインで使う

WiFiLocation.towers でアクセスポイントのMacアドレスと電波強度だけを取得できる(googleには送らない)
これはオフラインでも使える。
whereami –towers も同様。


ライフログ的な

crontabに
*/5 * * * * ruby -e 'puts "#{Time.now.to_i}\t#{`whereami --towers`}"' >> ~/wifi-towers.txt
とか書いておく。5分毎に~/wifi-towers.txt にunixtimeと電波状況が保存される。


インターネットに接続してからまとめて位置情報に変換してみる
cat ~/wifi-towers.txt | ruby -rjson -rwifi_location -lane 'a=$_.split(/\t/); time = Time.at a[0].to_i; loc = WiFiLocation.location JSON.parse a[1]; puts "#{time}\t#{loc.inspect}"'

結果が出てくる。
2012-08-03 20:05:00 +0900       {"latitude"=>35.5470762, "longitude"=>139.6434858, "address"=>{"country"=>"日本", "country_code"=>"JP", "region"=>"神奈川県", "city"=>"横浜市", "street"=>"3丁目", "street_number"=>"14"}, "accuracy"=>45.0}
2012-08-03 20:10:00 +0900 {"latitude"=>35.5823082, "longitude"=>139.663203, "address"=>{"country"=>"日本", "country_code"=>"JP", "region"=>"神奈川県", "city"=>"川崎市", "street"=>"1丁目", "street_number"=>"667"}, "accuracy"=>49.0}
2012-08-03 20:15:00 +0900 {"latitude"=>35.69384, "longitude"=>139.703549, "address"=>{"country"=>"日本", "country_code"=>"JP", "region"=>"東京都", "city"=>"新宿区", "street"=>"1丁目", "street_number"=>"4"}, "accuracy"=>166000.0}


WiFiのBSSID取得するコマンド、ネイティブアプリなら誰でも実行できるし、ブラウザやスマホと違ってダイアログも出ないからほんと変なアプリは入れないようにしたほうが良いと思う

0

Mountain Lionでnative extensionなrubygemsがビルド出来ない

/usr/bin/makeが消滅していたので、XCode4.4入れた。でもまだmakeが無い。
Command Line Tools for OSXをインストールしたらmakeが使えるようになった。

それでも

gem install ffi
等がビルドできない。/usr/bin/gcc-4.2が無かった。

sudo ln -s /usr/bin/llvm-gcc-4.2 /usr/bin/gcc-4.2
sudo ln -s /usr/bin/llvm-g++-4.2 /usr/bin/g++-4.2
これでnative extensionなrubygemインストールできるようになった。
thin, ffi, phidgets-ffi, zmq, mongo, eventmachine, nfc, sys-filesystem等のgemをビルドして動作確認した。

参考:ruby on rails – Not able to install some gems after mountain lion upgrade – Stack Overflow