ぬけラボ

φ(..)メモメモ

Rubyでの各メソッド実行時間測定

Rubyでの各メソッド実行時間測定方法を知らなかったのでメモ
こんなコードを書いて

$ vim test.rb
arr = [:hoge,:fuga,:moge]
arr.each{|i|puts i}

実行

$ ruby -r profile test.rb
hoge
fuga
moge
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
  0.00     0.00      0.00        2     0.00     0.00  IO#set_encoding
  0.00     0.00      0.00        3     0.00     0.00  Symbol#to_s
  0.00     0.00      0.00        6     0.00     0.00  IO#write
  0.00     0.00      0.00        3     0.00     0.00  IO#puts
  0.00     0.00      0.00        3     0.00     0.00  Kernel.puts
  0.00     0.00      0.00        1     0.00     0.00  Array#each
  0.00     0.01      0.00        1     0.00    10.00  #toplevel

それっぽいのが出てきた。
rオプションでの読み込みならばコード内でrequireでも良いのではと思い。

require 'profile'
arr = [:hoge,:fuga,:moge]
arr.each{|i|puts i}

実行

$ ruby test.rb
hoge
fuga
moge
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
  0.00     0.00      0.00        2     0.00     0.00  IO#set_encoding
  0.00     0.00      0.00        3     0.00     0.00  Symbol#to_s
  0.00     0.00      0.00        6     0.00     0.00  IO#write
  0.00     0.00      0.00        3     0.00     0.00  IO#puts
  0.00     0.00      0.00        3     0.00     0.00  Kernel.puts
  0.00     0.00      0.00        1     0.00     0.00  Array#each
  0.00     0.01      0.00        1     0.00    10.00  #toplevel

同じ結果が得られた。

詳しい説明はリファレンスマニュアルの方に
http://www.ruby-lang.org/ja/old-man/html/profile.html

またこちらの下の方に以下の補足がある。
>profileはそれ自身がオーバーヘッドになるためメソッド呼び出しあたりの処理時間がかなり遅くなります。[RAA:RbProf]というのがあり、こちらの方が速いようです

rubyでライブラリ/コマンド作成、gem公開までの流れ

※記載したコマンド例は作業の流れを示すためのサンプルです。

bundler インストール

$ gem install bundler

bundle gemでテンプレート作成

$ bundle gem hoge

gemspecファイル修正

descriptionとかsummaryを適切に編集

$ vim hoge.gemspec

libにプログラム作成

ライブラリとなるプログラムを作成

$ vim lib/hoge.rb

GemfileやRakefileを適切に編集

gemやrakeタスクを適切に編集

$ vim Gemfile
$ vim Rakefile

コマンド作成

例としてhoge-cmdコマンドを作成

$ mkdir bin
$ touch bin/hoge-cmd
$ vim bin/hoge-cmd
#!/usr/bin/env ruby
require "hoge"
...
コマンド実行プログラムを記述
...
$ chmod +x bin/hoge-cmd
$ vim bin/hoge-cmd

テスト作成

適切にテストを作成

$ mkdir test
$ touch test/helper.rb
$ touch test/test_hoge.rb

gem作成

rake buildでpkgディレクトリ以下にgemファイルが作成される

依存関係のあるライブラリ情報をgemspecファイルに記述
$ vim hoge.gemspec
$ git add .
$ git commit -m "first commit"
$ rake build

gemインストール

インストールするとhoge-cmdコマンドが使用可能になる

$ gem install pkg/hoge-0.0.1.gem

rubygemsに公開

十分慎重に...

$ rake release

CentOS6.3にソースコードからRubyをインストール

普段行なっているRubyのインストール手順と設定をメモ

1.インストール準備

$ sudo mkdir -p /var/service/nuke/local/ruby
$ sudo mkdir /var/service/nuke/local/src
$ cd /var/service/nuke/local/src

2.yamlのインストール

ruby193でyamlが必要なので先にインストール

$ sudo wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
$ sudo tar xzvf yaml-0.1.4.tar.gz
$ cd yaml-0.1.4
$ sudo ./configure --prefix=/var/service/nuke/local
$ sudo make && sudo make install
$ cd ..

3.rubyのインストール

1.8系と1.9系をインストールする

  • ダウンロード
$ sudo wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p371.tar.gz
$ sudo wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p362.tar.gz
  • 展開
$ ls -d ruby-*.tar.gz | xargs -i sudo tar zxf {}
$ ls -d ruby-*[^tar.gz]
ruby-1.8.7-p371  ruby-1.9.3-p362
  • インストール

1.8系

$ cd ruby-1.8.7-p371
$ sudo ./configure --prefix=/var/service/nuke/local/ruby/ruby-1.8.7-p371 --enable-shared --disable-install-doc --with-opt-dir=/var/service/nuke/local
$ sudo make && sudo make install
$ cd ..

1.9系

$ cd ruby-1.9.3-p362
$ sudo ./configure --prefix=/var/service/nuke/local/ruby/ruby-1.9.3-p362 --enable-shared --disable-install-doc --with-opt-dir=/var/service/nuke/local
$ sudo make && sudo make install
$ cd ..

4.環境変数の設定

以下を追記

$ vim ~/.bash_profile
PATH=/var/service/nuke/local/ruby/ruby-current/bin:$PATH:$HOME/bin
export PATH

反映

$ source ~/.bash_profile

5.シンボリックリンクの作成

$ pwd
/var/service/nuke/local/ruby
$ sudo ln -s ruby-1.9.3-p362 ruby-current
#=> ruby-current -> ruby-1.9.3-p362

rubyのバージョンを確認

$ ruby -v
ruby 1.9.3p362 (2012-12-25 revision 38607) [i686-linux]

使用したいRubyのバージョンを変更するときは、シンボリックリンク先を変更する
(例)使用するバージョンをruby1.9系からruby1.8系へ変更

$ sudo rm ruby-current
$ sudo ln -s ruby-1.8.7-p371 ruby-current

rubyのバージョンを確認

$ ruby -v
ruby 1.8.7 (2012-10-12 patchlevel 371) [i686-linux]

Ruby193で乱数字生成

こんな方法があったのか!と驚いたのでメモ

  • 配列
[*0..9, *'a'..'z', *'A'..'Z'].sample(10).join
#これでも出来る [*0..9, *'a'..'z', *'A'..'Z'].sample(10) * ""
#=> "eBoO8LnmIT"
  • securerandom
require 'securerandom'
SecureRandom.base64[0..9]
#=> "Bm00Gza1eJ"

Ruby193でnamedcaptureメモ

正規表現でマッチした物を変数として使えるやつ
fluentdの設定ファイルでよく使うのでメモ

hoge = "#{Time.now.to_i}\t#{Time.now.sec}\t#{Time.now}"
hoge[/^(?<time>.*)\t(?<hoge>.*)\t(?<fuga>.*)$/]
p $~[:time] #=> "1355798336"
p $~[:hoge] #=> "56"
p $~[:fuga] #=> "2012-12-18 11:38:56 +0900"

Ruby193でファイルカウンター

Rubyでファイルカウンターが必要になったのでメモ
ここが参考になりました
http://doc.ruby-lang.org/ja/1.9.2/method/File/i/flock.html

#encoding: utf-8
class Counter                                          
  def initialize(file)                                 
    @file = file                                       
  end                                                  

  def increment
    begin
      until File.exist?(@file) do
        open(@file, "w") do |f|
          f.write 0
        end
      end
      counter = 0
      open(@file, "r+") do |f|
        f.flock(File::LOCK_EX)
        counter = f.gets.to_i + 1
        f.rewind
        f.write counter
        f.flush
        f.truncate(f.pos)
        f.flock(File::LOCK_UN)
      end
      format("%08d",counter)
    rescue => ex
      puts ex
      "E" + [*0..9, *'a'..'z'].sample(7).join
    end
  end
end

cnt = Counter.new("count.txt")
puts cnt.increment #=> 0000001

同時にアクセスしてみる

$ ruby counter.rb & ruby counter.rb & ruby counter.rb & ruby couter.rb & ruby counter.rb
0000001
0000002
0000003
0000004
0000005

node.js導入メモ

macにnode.jsを導入(正式にはnodeと言うらしい。バージョン番号は0.偶数.xが安定版

homebrewでnodeをインストール

本体

$ brew install node
$ node -v
v0.8.15

npmインストール

パッケージ管理

$ wget -nd -O - http://npmjs.org/install.sh | sh -
$ npm -v
1.1.68

動作テスト

以下の内容のスクリプト作成

//node-test.js
var http = require('http');
var server = http.createServer(function (req, res){
  res.writeHead(200, {'Content-Type':'text/plain'});
  res.end('Hello World\n');
}).listen(8124, "127.0.0.1");

var server = http.createServer(function (req, res){
  res.writeHead(300, {'Content-Type':'text/plain'});
  res.end('Hello World\n');
}).listen(8125, "127.0.0.1");

var server = http.createServer(function (req, res){
  res.writeHead(400, {'Content-Type':'text/plain'});
  res.end('Hello World\n');
}).listen(8126, "127.0.0.1");

console.log('start http server');

node起動

$ node node-test.js
start http server

各ポート番号のページのステータスコードが以下のようになる

localhost:8124 → status code 200
localhost:8125 → status code 300
localhost:8126 → status code 400