ここでは ruby について書く。
どうでもいいけどcannaの漢字変換は何とかならないのだろうか。
おばかでしょうがない。

ちなみに(ちなむな) 俺もソートーおバカなので
このページの順序は何にも考えずに書いている。
かなり見にくいぞ!このページ -> 自分が。

簡易メニューで Jump するのじゃ
頭に戻る



真偽値
Rubyでは false と nil 以外の全ては真になる。
0、" "(空文字)、"hello, world!"も になる。
だから C言語でよく使う
  if 0 ...
みたいな無限ループは作れない。
やるなら
  if true
   print hello
  end
とする。

  true...常に真を示す。
  false..常に偽を示す。
  nil....初期化されていない事を示す。条件判断の時には偽と見なされる。
  で、これらと同じ値を持つ定数のTRUE,FALSE,NILもあるそうな。

その他に、
  __FILE__ 現在読み込み中のソースファイル名。
  __LINE__ 現在読み込み中のソースファイルの行番号。
っていうのも定数にあるんだって。

頭に戻る



変数の種類とスコープ
rubyでは変数名で変数のスコープや種類を決定しているので、変数の宣言が不要
変数を見ただけでその種類が分かるからプログラムが見やすくなるんだって。

ローカル変数(小文字または、"_"で始まるもの)
  i, foo, pat, line, 等
  使う前に必ず代入しないといけない。
  ローカル変数はスコープの中で最初に代入されたところから、
  そのスコープの最後までがその寿命。
  但し、ブロック(while, do, 等)だけは外側のスコープの変数にアクセス出来る。
  だから、下のgrep1.rb の pat はローカル変数なんだけど、
  whileの中からアクセスできたんだって。

2003.04.20
ローカル変数のスコープは、メソッド、クラス、モジュール定義の内側になる。

グローバル変数("$"で始まるもの)
  どこからでもアクセス可能なので、分かりにくいプログラムになりやすい。
  なるべく使わないようにしませう。

インスタンス変数("@"で始まるもの)
  良く分かんないけど、オブジェクトの初期化メソッドは
  initialize で代入しておくことがオキテなんだって。

定数(大文字で始まるもの)
  まんま。
  一度代入して、それ以降変更不可。

疑似変数(self, true, false, nil, __FILE__, __LINE__,等)
  self...わけわか。使うことも無いでしょう。
         自分自身を示すんだって。
         print, puts, gets などが該当して、
         selfのおかげでこれらの関数(メソッド?)が簡単に使えるらしい。
         true,false,nilはローカル変数の外見をした定数。

頭に戻る



grep でお勉強

grep1.rb
#!/usr/bin/ruby
# grep1.rb patttern file, ...
#
pat = /#{ARGV.shift}/        //は正規表現オブジェクトを示す。
while line = gets()          引数から一行読み込んで変数lineに入れる。
  if pat =~ line             lineの内容とパターンを比較。
    print line               マッチしたその行を表示。
  end
end

こんな風にもかけまふ。
grep2.rb
#!/usr/bin/ruby
# grep2.rb pattern file,...
#
$pat = ARGV.shift              第一引数のパターン読み込み。
while $_ = gets()              第二引数以降のファイルから1行ずつ読み込み。
  if $_ =~ /#{$pat}/ then      パターンマッチング。
     print $_                  マッチした行を表示。
  end
end

ちなみに $_ は gets などで最後に読み込んだ文字列がかってに入るローカル変数なのでこんな風に省略できま。
grep3.rb
#!/usr/bin/ruby
# grep3.rb pattern file,...
#
$pat = ARGV.shift
while
  gets
    print if /#{$pat}/   if 条件式の別の書き方。
end                      実行部分を前に置けるのでスッキリ見える。

ここで、gets のカッコがなくなっちゃったけどエラーにはなりません。

ruby には組み込みメソッドというものがあって、gets,print,exit,chop
などががそれにあたります。
組み込みメソッドは、メソッドが返す値(戻り値)を使わない時には
(曖昧でなければ)カッコは省略可。
だから、  print("hello,world") と、
        print "hello,world"
は同じ意味になります。

頭に戻る



漢字(日本語)の扱いに付いて。
Rubyの作者が日本人なので始めから日本語の処理が可能。
  実は Ruby を始めようと思ったきっかけがこれ↑。
  なんか楽そうじゃん。

Rubyの扱える文字コードは下の4種類の内のどれか。
 EUC, SJIS, UTF-8,NONE(日本語を意識しない)

指定は Ruby 起動時のオプション -K、またはプログラム中の$KCODEで行う。
  EUC.... e 又は E
  SJIS... s 又は S
  UTF-8.. u 又は U
  NONE... n 又は N

例えば、起動オプションに
  #!/usr/bin/ruby -Ks
を書けば、SJIS を指定した事になる。

また、標準の状態では日本語対応の正規表現に対応していない
対応させるには jcode モジュールをあらかじめ読み込む(require 'jcode' を宣言する)必要がある。
これで String クラスのメソッド(chop,tr_s,upto,など)が日本語文字処理が出来ように置き換わり、 jlength が更に追加される。

また、文字コードの取扱には kconv を読み込む必要がある。
例) jgrep.rb        日本語処理可能なgrep.rb
#!/usr/bin/rubu
# jgrep.rb pattern file,...
require 'kconv'
pat = /#{Kconv::toeucARGV.shift}/e     /eで正規表現をEUCとみなし、
while line = gets()                    読み込んだ内容をEUCに変更。
  line = Kconv::toeuc(line)            line の内容を EUC に変更。
  if pat =~ line
    print line
  end
end

理解不能な grep の例
rgrep.rb
# rgrep.rb
# 2001.03.25
# usage: rgrep.rb pattern
# this include bug
# error message: rgrep.rb:11: parse error
require 'find'
pat = /#{ARGV.shift}/
Find::find(".") do | path |
  next unless Find::find ? ( path )   # this line is error
  open( path ) do | f |
    while line = f.gets()
      if pat =~ line
        print path,":",line, "\n"
      end
    end
  end
end

Linux magazin の例題を打ち込んでみたんだけど、、、
parse error って文法エラー?
Find::find の後の"?"の使い方がよくわかんない。
だいたい||ってなに?
リナマガのばかーーー、ってかんじ。

頭に戻る



ワンライナースクリプト
-e に n または p をつけて ruby を起動する。
-ne: 引数で指定した各ファイルから一行ずつ読み込んで、その各行を $_ に入れる処理を繰り返す。
-pe: -ne と似ているけど、繰り返し処理の最後で $_ を print する(らしい)。

例:
Hello, World を表示。
$ ruby -e 'print "Hello, World! \n"'

file の内容を表示。
$ ruby -ne 'print $_' file(s)
cat file(s) と同意。

また、$_ は省略できるので、
$ ruby -ne 'print' file(s)
でも可。

ワンライナーgrep
file中に "abc" が含まれたら、その行を表示。
$ ruby -ne 'print $_ if /abc/ =~ $_' file

$_ は省略できるので、
$ ruby -ne 'print if /abc/' file
となる。

日本語(漢字コード)の検索
-K オプションを着けるだけでオッケー。
$ ruby -Ke -ne 'print if /ほげほげ/' file

  e: 日本語EUC
  s: シフトJIS
  u: UTF-8

頭に戻る



irb ( interactive ruby 対話型 Ruby )
コマンドラインから直接起動。
$ irb
irb(main):001:0>

ctrl + d 又は、exit で終了。

使ってみる。
$ irb
irb(main):001:0> def fact(n)
irb(main):002:1> if n == 0
irb(main):003:2> 1
irb(main):004:2> else
irb(main):005:2* n+fact(n-1)
irb(main):006:2> end
irb(main):007:1> end
nil
irb(main):008:0> fact(10)
56
irb(main):009:0> exit
$

頭に戻る



open
ファイルのオープン
使いかたは Ruby script 中で
f = open("/usr/share/dict/words")
f.grep(/Ruby/){|line| pirnt line}
f.close
みたいにする。
この意味は、/usr/share/dict/words という辞書ファイルから Ruby という単語を含んでいる行を出力。
また、open は File クラスのオブジェクトを返す。

open メソッドの引数は
open(path[,mode[,perm]])
path は開きたいファイルのパス、ファイル名も含む。
mode は開くファイルの入出力モードで、文字列、又は、整数フラグで指定。
     デフォルトは読み込みモード"r" 又は RDONLY。
perm は新しいファイルが作られた時のパーミッション。

modeで指定できる入出力モード(文字列)
文字列 入出力モード
"r" 読み込みのみ。ファイルが存在しない場合はエラーになる
"r+" 読み込み+書き込み。ファイルが存在しない場合はエラーになる
"w" 書き込みのみ。ファイルがなければ新規作成。あればサイズを0にする。
"w+" 読み込み+書き込み。ファイルがなければ新規作成。あればサイズを0にする。
"a" 追加書き込み。ファイルがなければ新規作成。ファイル末尾にseekする。
"a+" 追加読み込み+書き込み。ファイルがなければ新規作成。ファイル末尾にseekする。

整数フラグには基本的な動作モードと、それを補うモードを"|"(ビットOR)で複数指定出来て、
open(path,File::RDWR|File::CREATE, 0666)
見たいに使う。
定数 基本的な入出力モード
RDONLY 読み込み
WRONLY 書き込み。
RDWR 読み込み+書き込み。

定数 補助的な入出力モード
CREAT 指定したpathにファイルが存在しない場合は作成する。この定数が指定されない場合、ファイルが存在していなければエラーになる。
EXCL CREATと一緒に指定された場合、ファイルが既に存在した場合にエラーになる。
NOCTTY 指定したpathがterminalデバイスを参照していて、かつプロセスが制御端末を持たない場合でも、そのterminalが制御端末にならない。
TRUNC ファイルが既に存在し、通常ファイルであり、書き込み可能モード(RDWR又はWRONLY)が指定されている場合、そのファイルの長さは0に切り詰められる。
APPEND ファイルを追加モードでオープンし、ファイル末端にseekする。
NONBLOCK
NDELAY
ファイルをnonblockingモードでオープンする。openを始めとする、ファイルディスクリプタに対する全てのシステムコールはブロックしない。ブロックが発生しそうな場合にはシステムコールが失敗する。
SYNC ファイルを同期I/Oモードでオープンする。ファイルディスクリプタに対する全てのwriteは、実際に書き込みが完了するまで終了しない。


open で実行ファイルを実行
洒落じゃないんだけどな。

open は第一引数が ""で始まるとそれに続く文字列をコマンドとして解釈して実行してくれる。
さらに、"|-"になったときはrubyインタプリタをforkして子プロセスを作って、その子プロセスの標準入出力との間にパイプラインをつなぐ(らしい。全くわかんない。)。

何をやっているか分かる?

#!/usr/bin/ruby

f = open ( "/home/jun1/rpm/SPECS/bluefish.spec" )
f.grep(/bluef/){|line| print line}
f.close
  /home/jun1/rpm/SPECS/bluefish.spec を開いて、
  文字 "bluef" に該当する行を出力

f = open( "|/home/jun1/bin/beep-beep" )
f.close
  /home/jun1/bin/beep-beep を実行型式で開いて、鳴らして、

open("|/bin/sleep 3") do |i|
end
  sleep で3秒まってから、

open( "|/home/jun1/bin/beep-beep") do |f|
end
  もう1回 beep-beep を鳴らす。

と、言う風に、open の仕方もいろいろ(2種類?)あって
f = open ( path )
begin
  hogehoge
ensure
  f.close
end
よりも、

open ( path ) do |f|
  hogehoge
end
の方が推奨されているらしい。
途中でエラーが起きたり、例外などで実効を中断しても必ずファイルがクローズされるから、
だってさ。

で、open はファイルとコマンドの両方を開く事が出来る高機能なメソッドだけど ファイルしか開かない事が決まっている時は File クラスのメソッドを使える。

  File::new(path[, mode[, perm]])
  File::open(path[, mode[, perm]])

意味はファイルを開く時の open の使いかたと同じ。
当前、path の前に""を着けてもこれは無視される。
このメソッドは File クラスのオブジェクトを返す。

で、逆にコマンドを開くだけの場合は

  IO::popen(cmd[, mode])
が使える。

IO::popen は open と同様にブロックを取り、戻り値は IO クラスのオブジェクト。

なんとなく面白そうだから ls を使って見ようとして
  #!/usr/bin/ruby
  IO::popen( "/bin/ls" ) do | i |
  end
ってやっても表示できないのね。
なんか別のやり方があるんだろうな。

ちなみに、
  #!/usr/bin/ruby
  f = IO::popen( "/bin/ls" )
  f.close

もダメだった。うんともすんともいいやしねー。

頭に戻る



puts

puts には、こんな使いかたもできまふ。

$ cat t.rb
> #!/usr/bin/ruby
> puts 1 + 2

$ ruby ./t.rb
> 3

頭に戻る



コマンドライン引数に指定されたファイルのそれぞれの行数を表示

/usr/bin/wc -l と同じことをするだけ。

 # total:  総行数  
 # nfile:  ファイル数
 total = 0 
 nfile = 0 
 
 for file in ARGV 
   n = 0 
   File::foreach( file ) do 
     n += 1 
   end 
   printf "file %s has %d lines \n", file, n 
   total += n 
   nfile += 1 
 end 
 printf "total %d files %d lines \n", nfile, total  
これのモノホンはここね。

ARGV はコマンドライン引数で指定されたファイル名が入っていて、そのファイル数だけ for 文が回り、そのたびに file にファイル名が代入される。

File::foreach(file) は file で指定したファイルの各行に対して繰りかえす手続。
今回は行数を数えるだけなので n += 1 でカウントしている。

同じようなものもあるでよ。
これは software design のサンプルプログラムで、文字数、単語数も数えるぜよ。

頭に戻る



メタ文字

/abc/ =~ line
は、文字列 line の中に abc という文字が含まれていたら正となる。

 。  任意の一文字
 *  直前の表現の0回以上のくり返し
 +  直前の表現の1回以上のくり返し
 ?  直前の表現の0回か、1回のくり返し

[]はその中に入っているどれか一文字にマッチ。
a[bc]dは、abd、acd、にマッチ。

[]の中の先頭の^は、その中に入っている文字以外にマッチ。
[^acーe]は、a,c,d、e以外の一文字にマッチ。
[]の中以外の^は、文字列の先頭を意味する。
^aは、aで始まる文字列にマッチ。
$は、行末を意味する。

 \\、\。、\*、\+、\?、  \ 。 * + ? という文字そのもの/td>
 \d  数字のクラス
 \w  英数字のクラス
 \s  空白文字(スペース、タブ、改行)のクラス
 \D、\W、\S  それぞれの小文字の補文字(以外)クラス

\dは、[0ー9]にマッチ。
\Dは、[^0ー9]にマッチ。

()カッコで囲まれた正規表現にマッチした文字列は、変数$1、$2に保存される。
/(。*):(\d+)/ = ̄ "foo:8080" は、$1ー>"foo" $2ー>"8080"


頭に戻る





頭に戻る





頭に戻る






戻る