Hatena::Grouprubyist

payaparaの日記 このページをアンテナに追加 RSSフィード

2009-09-29

RubyのTestCaseの便利さを実感。

23:54 | RubyのTestCaseの便利さを実感。 - payaparaの日記 を含むブックマーク はてなブックマーク - RubyのTestCaseの便利さを実感。 - payaparaの日記 RubyのTestCaseの便利さを実感。 - payaparaの日記 のブックマークコメント

マーチンファウラー著のリファクタリングの中でJavaのTestCaseを構築方法が載ってありましたが、

正直コードが理解しにくく、TestCaseを書いてもあまり利益があるのかと疑問でした。

でも、RubyのTestCaseはとてもわかりやすかったので、少しTestCaseについて書きます。

TestCaseの書き方


 require "test/unit"
    
  require "テストしたい物"
   
   class テストしたい物のテストケース < Test::Unit::TestCase
  
    def setup
      @obj = テストしたい物の中のクラス.new
    end

    def test_メソッド名
      assert_equal(メソッドの実行結果を比較する物, @obj.メソッド名())
    end
 end

例えばObj.rbにこんなメソッドがあったとします。

## Obj.rb
 #リストを抽出する。
210   def list(value)
211     value.split(',')
212   end

このメソッドはどういうことをするのか知りたいときは

      @obj = Obj.new
      puts @obj.list("1,2,3")

表示してくれて挙動が分かった。

ていうのは今まで...

ちゃんとtestCaseを書く。

#! /usr/bin/env ruby

## ObjTestCase.rb

 require "test/unit"
    
  require "Obj.rb"
   
   class ObjTestCase < Test::Unit::TestCase
  
    def setup
      @obj = Obj.new
    end

    def test_list
      assert_equal("", @obj.list("1,2,3"))
    end
 end

ここでテストしてみます。

% ObjTestCase.rb

Loaded suite /home/user/ruby/ObjTestCase

Started

.F.

Finished in 0.029616 seconds.

1) Failure:

test_list(ObjTestCase) [/home/user/ruby/ObjTestCase.rb:22]:

<""> expected but was

<["1", "2", "3"]>.

1 tests, 1 assertions, 1 failures, 0 errors, 0 skips

listメソッドは["1","2","3"]を返しているようです。

失敗しているのはassert_equalの結果で

["1","2","3"] が "" と違うと言ってくれている。

だから["1","2","3"]を入れてみる

   def test_list
       assert_equal(["1","2","3"], @obj.list("1,2,3"))
   end

すると

% ObjTestCase.rb

Loaded suite /home/user/ruby/ObjTestCase

Started

...

Finished in 0.030652 seconds.

1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

成功する。

こんな感じでTestCaseを増やしていく。

  def test_coexist
      assert_equal([1, 2, 3..6, [1, 3, 5], [0, 2, 4], [3, 6, 9]],
                                  @Obj.coexist("1,2,3-6,1-5/2,0-5/2,3-9/3"))
      assert_equal([1, 3, 4], @Obj.coexist("1,3,4"))
  end

  def test_list
    assert_equal(["1", "2", "3", "45", "55"], @Obj.list("1,2,3,45,55"))
    assert_equal(["1","2","3"], @Obj.list("1,2,3"))
  end
 
  def test_range
    assert_equal([1,3,5], @Obj.range("1-5/2"))
    assert_equal([], @Obj.range("6-5/2"))
  end

assert_equalばかりですが、

他のメソッドもあります。http://doc.okkez.net/191/view/library/test.unit

http://doc.okkez.net/191/view/class/Test=Unit=Assertions

書くのはめんどくさいかもしれないですが、書いてる内にプログラムの内容が

頭に整理されていくような気がします。それとわざと失敗を誘うと

メソッドの挙動が分かるのでそれを利用すればよいかもしれません。

2009-06-30

cronをsuspend状態からでも、実行できるようにする。ubuntu 8.10

18:56 | cronをsuspend状態からでも、実行できるようにする。ubuntu 8.10 - payaparaの日記 を含むブックマーク はてなブックマーク - cronをsuspend状態からでも、実行できるようにする。ubuntu 8.10 - payaparaの日記 cronをsuspend状態からでも、実行できるようにする。ubuntu 8.10 - payaparaの日記 のブックマークコメント

動機

linuxwindowsのようなタスク機能がない。

・cronはsuspend状態から実行できない。

・目覚まし機能をつけたい。

Rubyでいろいろしたい。

など...



準備


初めにやっておくこと

・復帰からのパスワード入力をなしにする。

% gconf-editor

suspendのチェックをはずす。


PC復帰について

参考にさせってもらったサイト

PCを指定時刻に起動する

http://lostman-worlds-end.blogspot.com/2008/12/pc.html

PCのアラーム設定。

http://www.mythtv.org/wiki/ACPI_Wakeup#Using_.2Fsys.2Fclass.2Frtc.2Frtc0.2Fwakealarm

上記のサイトのおかげでsuspend状態からでも(多分shutdownからでも)

PCが復帰できました。



簡単に説明すると


$SECSに1970-01-01 00:00:00 UTC からの秒数を設定

echo 0 > /sys/class/rtc/rtc0/wakealarm アラームを初期化

echo $SECS > /sys/class/rtc/rtc0/wakealarm アラームを設定


これでだけでPCが復帰します。

しかし、パーミッション云々などの問題で私はハマりました。

そのため、スクリプトを作っておくといいです。


% vim alarm.sh



#!/bin/sh

if [ $# -ne 2 ];

then

echo usage:

echo $0 `date +%F" "%T`

exit

fi

SECS=`date -u --date "$1 $2" +%s`

echo 0 > /sys/class/rtc/rtc0/wakealarm

echo $SECS > /sys/class/rtc/rtc0/wakealarm

cat /proc/driver/rtc


alarm.shの使い方

% chmod 755 alarm.sh

% sudo ./alarm.sh 2009-06-26 12:45:00 ##時刻を直接設定

##現在の時刻の5分後に設定

% sudo ./alarm.sh `date +%F" "%T -d '+ 5 minutes'`

rtc_time : 22:05:01

rtc_date : 2009-06-27

alrm_time : 22:10:00  ## ここが表示されれば成功

alrm_date : 2009-06-27 ##

alarm_IRQ : yes

alrm_pending : no

24hr : yes

periodic_IRQ : no

update_IRQ : no

HPET_emulated : yes

DST_enable : no

periodic_freq : 1024

batt_status : okay

あとはPCが復帰するかsuspendしてテストしてみてください。




cronと連携

cronを実行するにはPCが動いていなければならないので、

Rubyを使って実行五分前に復帰できるようなプログラムを

作りたいと思っていました。

http://bitbucket.org/shiro/cronwakeuprb/src/tip/cronWakeup.rb


あとはこれを実行するタイミングですが、

やはりsuspendをする前が絶妙です。

参考サイト http://www.revulo.com/blog/20090512.html

Ubuntu8.10では

% /etc/pm/sleep.d/

にスクリプトを置いておくとsuspendやshutdown前にプログラムが実行されるようです。


ソースを入手と解凍

% wget -O cronWakeup.gz http://bitbucket.org/shiro/cronwakeuprb/get/tip.gz

% tar zxvf cronWakeup.gz

ファイル実行権限を変更

% cd cronwakeuprb/

% chmod 755 cronWakeup.rb

実行するスクリプトを置く

% cd /etc/pm/sleep.d/

% sudo vim 01-cron-suspend-alarm.sh

#!/bin/sh

/home/user/cronwakeuprb/cronWakeup.rb init

root権限で実行するように設定

% sudo chmod 755 01-cron-suspend-alarm.sh

% sudo chown root:root 01-cron-suspend-alarm.sh



cronWakeup.rbのについて

使い方

% sudo cronWakeup.rb init  #アラームを設定

% cronWakeup.rb list -l #アラーム時間を列挙

特定のプログラムしか復帰したくないという場合は

rootユーザーで分けると便利かもしれません。

% sudo crontab -e   #rootのcrontabを設定

設定...

% sudo cronWakeup.rb init -u root #rootのcrontabのみ復帰


問題

時間設定が完璧でない。

% crontab -e

でcronを設定できます。

0 18 * * *

は設定できますが、

範囲設定やリスト設定は使えません。

0 10-13 * * *

上記設定使えません。



今後

上記の問題を解決できたらいいなと思っています。

あとはリファクタリングしていきたいです。

何かご指摘あれば、よろしくお願いします。



その他

cronを駆使してamarokをコントロールするという

似たようなプログラムを発見しました。

http://www.arsoft-online.com/index.php?option=com_content&view=article&id=27:amarok-alarm&catid=26:alarm&Itemid=48

2009-04-28

refe2使っている人いますか?

02:11 | refe2使っている人いますか? - payaparaの日記 を含むブックマーク はてなブックマーク - refe2使っている人いますか? - payaparaの日記 refe2使っている人いますか? - payaparaの日記 のブックマークコメント


% refe String

とすると

class String < Object

include Comparable

文字列のクラスです。

NUL 文字を含む任意のバイト列を扱うことができます。

文字列の長さにはメモリ容量以外の制限はありません。.......


とこんなかんじで出てくる。


% refe String#

とすると


String#% String#* String#+ String#<< String#<=> String#== String#=~

String# String#= String#ascii_only? String#bytes String#bytesize

String#capitalize String#capitalize! String#casecmp String#center

String#chars String#chomp String#chomp! String#chop String#chop!

String#chr String#clear String#codepoints String#count String#crypt

......


とこんなかんじ。

う〜見にくいな。

ということで見やすく


% refe String# | grep -o -e "String#[a-zA-Z0-9_?\!%*+<>=~]*\W*"

String#%

String#*

String#+

String#<<

String#<=>

String#==

String#=~

String#[]

String#[]=

String#ascii_only?

...


見やすくなったでも長い・・・

横にメソッドの説明するようにできないでしょうか?


String#% printf と同じ規則に従って args をフォーマットします。

String#* 文字列の内容を times 回だけ繰り返した新しい文字列を作成して返します。

String#+ 文字列と other を連結した新しい文字列を返します。

...


とこんな感じで

正規表現でパパッと。


% refe String | grep "。" | grep -n -e "。" | grep "^1:"

1:文字列のクラスです。




説明文抽出するだけでできませんでした。orz...また今度



>>>続き↓

mas-higaさん情報ありがとうございます。


ということでrubyでソース書いてみました。


#! /usr/bin/env ruby
# vi: set fileencoding=utf-8 :
## referb.rb

if $* == []
  refeString = `refe -l`
  refeString.each_line() {|line|
  print line + %x{refe "#{line.chomp}" | grep '。' | grep -n -e '。' | grep '^1:' | grep '。' | grep -o -e '[^1].*[。]$    '} + "\n"
  }
elsif $*[0][$*[0].length-1] == "#"
  refeString = `refe -l #{$*[0]}`
  refeString.each_line() {|line|
  print line + %x{refe "#{line.chomp}" | grep '。' | grep -n -e '。' | grep '^1:' | grep '。' | grep -o -e '[^1].*[。]$    '} + "\n"
  }
else
  refeString = `refe #{$*[0]}`
  puts refeString
end

んで

% referb.rb String#

とすると

String#%

:printf と同じ規則に従って args をフォーマットします。

String#*

:文字列の内容を times 回だけ繰り返した新しい文字列を作成して返します。

String#+

:文字列と other を連結した新しい文字列を返します。

....

になる

でも遅いしちゃんと抽出できてないので使えないなこれは...

bitclust解析したらできるかな?

mas-higamas-higa2009/04/29 20:01「見やすく」は refe -l String# でもよさそうですね。
説明は出ませんが。