2009年11月09日 methodの途中の作業
_ yieldを使う
rubyであるメソッドの途中で別の作業をしたいときに、その内容をブロックとして与えて、yieldで実行することができる。ブロックを与えないときには何もしないのかと思いきや、エラーが起こるので、yield if block_given?としておけば良い。
問題なのは、いくつかの操作をメソッドの途中でしたいときだ。ブロックは二つ与えられないしと思っていたら、こんな感じで実現できることに気がついた。
def test puts 0 yield(0) if block_given? puts 1 yield(1) if block_given? puts 2 end test{|i| case i when 0; puts 'a' when 1; puts 'b' end } test{ puts 'a' } testこれで、ブロックを付けなくてもエラーが出ないし、場合分けがあるかも意識しないでも良い。
しかし、手続オブジェクトを引数に使うと、複数の手続を指定できるので、素直に書ける。
def test(a=nil,b=nil) puts 0 a.call if a puts 1 b.call if b puts 2 end a=Proc.new{ puts 'a' } b=Proc.new{ puts 'b' } test(a,b) test(a) test()しかし、メソッドを呼び出す前に手続オブジェクトを定義しないといけないので、少し面倒な気がする。間をとって、こんな感じが使い易いのかも知れない。
def test(a=nil) puts 0 a.call if a.class==Proc puts 1 yield if block_given? puts 2 end test(Proc.new{ puts 'a' }){ puts 'b' } test{puts 'b'} test()一つのブロックなら普通に書けて、二つ以上の場合には、少し冗長になる。
2009年11月12日 新しい言語
_ goとscala
googleがあたらしい言語を発表したらしい。goというらしいのだが、便利なのだろうか。言語といえば、scalaというのも注目を集めているらしい。両方ともcompile言語で、簡単に書けるらしい。
最近は、ruby以外はめっきり書いていない。cも一年以上書いていない気がする。rubyの欠点はinterpreterなので、実行速度が遅いということである。rubyの一部の機能を制限すれば、compileも可能な気がするのだが、できないものなのだろうか。
実は、今もrubyを使って測定を行っている最中である。最初に同じ測定をやったときには、いろいろなことを手で行わなければならなかったので、大変だった。今ではそのほとんどを適当にやってくれるので、随分と楽になったものである。しかし、rubyで測定をやっている人は少ないのではないかと危惧している。この前、私が書いたwindowsからGPIBをrubyで叩くためのコードを使っている人をネット上で見付けて驚いた。私の書いたコードを誰かが使って少しでも役に立っていれば幸いである。
今後、学習しようと思っている言語として、javaとpythonがあるが、scalaもその候補に加えておこう。goはとりあえず様子見かな。
2009年11月16日 rubyの配列の作り方
_ rubyのArray
0から一ずつ増えていく整数を要素とする配列をつくるのに、Rだと0:9、pythonだとrange(0,10)などとすれば、簡単にできる。rubyでどうやるかわからなかったので、a=[];(0..9).each{|e|a<<e}とか(0..9).to_aでつくっていたのだが、実は[0..9]でよいらしい。
rubyを始めて結構たつが、こんなことも知らなかったとは。一行ぐらいで書けることは、調べるよりも書いた方が早いので、適当に書いて済ませてしまっているが、もう一度、一から勉強し直した方が良いのかも知れない。
_ 2010/1/13追記
今、実行してみると、[0..9]は0..9という要素をもつ配列にしかなっていない。おかしいな。どこで上のように勘違いしたのだろうか。
2009年11月17日 ruby-gslでfitting
_ Gaussianでfit
たくさんのデータをgaussianでfitする必要があって、どうやってやろうか考えた。グラフソフトを使って、手でするのはデータが多すぎて現実的ではない。Rはプログラムを組めるので、可能ではあるだろうが、gaussianのfitをどうするかまだ知らないので、別の方法を試みることにした。調べてみると、GSLというライブラリがあり、科学計算に用いるいろいろな道具が揃っているらしい。さらに、これがrubyからたたけるらしい。というわけで、rubyでgaussian fitをしてみた。まずは、aptitude install libgsl-rubyでインストール。Histogramだとfit_gaussianというmethodがあるようだが、これだとxyデータをそのまま扱えない。いろいろと探していたら、MultiFitでできることが分かった。こんな感じだ。
require "gsl" x=[0,1,2,3,4,5,6] y=[0,1,2,3,2,1,0] gx=GSL::Vector[*x] gy=GSL::Vector[*y] guess=[gy.min,gy.max,gx.mean,2] y0,int,x0,var=GSL::MultiFit::FdfSolver.fit(gx,gy,"gaussian",guess)[0].to_aいろいろと分からないことが多いが、配列を返してくるので、先頭にあるパラメータを取り出して、これがGSL::Vectorなので、rubyの通常の配列に戻して、結果を得ている。いろいろなデータを試してみると、明らかにピークがあるデータはうまくいくのだが、ピークがあるか無いかわからないようなデータだと、変な値になってしまう。ピークがなさそうなら、強度が0に近い値になって欲しいのだが。あとはこの辺りをなんとかしないと。
2009年11月26日 dellのdisplay
_ ディスプレイの修理
液晶ディスプレイが壊れた。症状から電源系統の故障だろうと判断して、直す気で中を開けてみた。すると、基盤にBENQの文字が。確かdellのだと思って枠を見てみると、DELLの文字。
肝心の修理の方は、一見してよく分からないのだが、陰極管への電圧をつくる回路と、制御系の回路へ電圧を供給するラインが分かれている。それぞれに別の電圧が供給されているようなのだが、その電圧が分からない。回路への供給は5Vだとは思うが、陰極管の方がよく分からない。時間もないし、面倒になってきて、結局捨ててしまった。もっと回路が分かるようになりたいな。
_ 2009/12/6追記
一度はすてようとした基盤だが、救出していろいろと調べた結果、インバーター回路の中の2SC5707というトランジスタが壊れているのが故障の原因らしいことが分かった。検索してみると、このような事例は結構多いようだ。直せるかもしれないが、他の部品は捨ててしまったので、復活は不可能である。結局、四つあるうちの一つしか壊れていないようなので、三つを部品取り用にすることになった。