只今Ruby勉強中

プログラミングRuby―達人プログラマーガイド

うさぎさんと一緒にRubyの勉強をしているオレの記録。

間違ってる所とかいっぱいあると思いますけど、誰でもコメント出来るので気軽に教えて下さい。

普段は 鷹の島 って所で書いてます。

現在のハマリポイント - yield, succ?, Proc & 後で

2006-08-31 (Thu)

RSS パーサー 18:32  RSS パーサー - 只今Ruby勉強中 を含むブックマーク

とあるサイトから RSS をいっぱい取ってきて整理して並べるっていう事をやりたかったのでやってみた。

最終的にこんな感じになった。ちょっと恥ずかしいけど、結構この rubyist グループの検索で過去に書いたのを見たりするので、まぁメモ的に。

#! /usr/bin/ruby

require 'open-uri'
require 'rexml/document'

def main
   (4367..5423).each do |i|
      begin
         xml = XmlParser.new(doGet(i))
      rescue
         next
      end

      puts i

      File.open('userscripts.txt', 'a') do |f|
         f.print '*', i, ' '
         f.puts xml.title
         f.puts xml.description
         f.puts
      end
   end
end

def doGet(num)
   prefix = 'http://userscripts.org/scripts/rss/'
   url = prefix + num.to_s

   begin
      open(url).read
   rescue
      throw 'load error'
   end
end

class XmlParser
   def initialize(data)
      doc = REXML::Document.new(data)
      @title = doc.elements['rss/channel/title'][0]
      @description = doc.elements['rss/channel/description'][0]
   end

   attr_reader :title, :description
end

main()

REXML の使い方がまだ良くわかんなくて適当。REXML は ruby1.8 には標準で付いてくるみたいで openurl もあるしかなり楽出来る感じで、あんまり時間を掛けずに動くように出来た。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060831

2006-08-30 (Wed)

ランダム配列の話題 14:33  ランダム配列の話題 - 只今Ruby勉強中 を含むブックマーク

近頃配列をランダムにソートする話しが 話題になっていますが、Random 関数を使ってソートをするやり方はダメ駄目でウンコって事でした。

そんで Fisher-Yates とかいうアルゴリズムの存在も知りまして、これは後ろからランダムで前方の値と入れ替えていく、みたいな、なんか頭良さげな方法でして理解出来るまで時間がかかったりした感じ。

この前 pigコマンド作った時slice するやり方を取ったけど、sort_by っていう方法もあったなーと思い、そういえばこの sort_by ってどんな動きをしているかどうか気になっていたので調べてみました。

リファレンス読んでも良くわからんので色々動かして試してみた所、どうやら単純にブロック内の結果順で並び替えるっていうだけのものでした。

それで、まぁ ruby-list でも話題になっていた randomize メソッドを考えた。

こんだけなんでメソッドにする程でもない。

class Array
   def randomize
      sort_by { rand }
   end

   def randomize!
      replace(randomize)
   end
end

動作チェックコード。

count = []
3.times { count << [0, 0, 0] }

10000.times do
   [0, 1, 2].randomize.each_with_index do |v, i|
      count[i][v] += 1
   end
end
p count

実行。

$ ruby rand.rb
[[3343, 3293, 3364], [3279, 3437, 3284], [3378, 3270, 3352]]

綺麗に出来た。

ちなみに randomize の実行部を sort { rand - 0.5 } にして実行するとこんな感じ。

[[3707, 2603, 3690], [2510, 4945, 2545], [3783, 2452, 3765]]

かたよりんぐ。

ようするに sort_by すごい便利って事で。

Object#methods 22:00  Object#methods - 只今Ruby勉強中 を含むブックマーク

WEB+DB PRESS: p172

はてナオヤさんの Perl の話題の所にさりげなく書いてあって、これはまさに知りたかったやつでした!

この前 mailread を使ったプログラムを書いた時にメソッド一覧が欲しい!って思ったんだけど、やり方わかんなくて断念して結局ソース見たら50行くらいのコードだったからソース見た方が早かったって事がわかってションボリ。

こんな風にすれば良いらしい。

irb(main):001:0> require 'mailread'
=> true
irb(main):002:0> Mail.methods
=> ["inspect", "autoload?", "send", "class_eval", "clone", "public_methods", "method", "protected_instance_methods", "__send__", "private_method_defined?", "equal?", "freeze", "methods", "instance_eval", "dup", "include?", "private_instance_methods", "instance_variables", "extend", "protected_method_defined?", "const_defined?", "instance_of?", "name", "eql?", "public_class_method", "object_id", "hash", "id", "new", "singleton_methods", "taint", "frozen?", "instance_variable_get", "constants", "kind_of?", "to_a", "ancestors", "display", "private_class_method", "const_missing", "type", "autoload", "<", "protected_methods", "<=>", "instance_methods", "==", "method_defined?", "superclass", ">", "===", "instance_variable_set", "instance_method", "const_get", "is_a?", ">=", "respond_to?", "to_s", "<=", "module_eval", "class_variables", "allocate", "class", "public_instance_methods", "tainted?", "=~", "private_methods", "public_method_defined?", "__id__", "nil?", "untaint", "included_modules", "const_set"]

うわぁ、これじゃちょっとワカンネ。ていうか、body とか header とか出てないし。間違ってるのか…。

yamazyamaz2006/08/31 18:47こんにちは.Mail.methodsはMailのクラスメソッド一覧取得なので,
Mail.new("ファイル名").methods で望みのモノが取得できると思います.

gabagaba2006/08/31 19:57おおおお、これだ!すごい!!ありがとうございます。
これで今後の開発が少し楽になりそうです。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060830

2006-08-29 (Tue)

LL Ring 感想追加 22:40  LL Ring 感想追加 - 只今Ruby勉強中 を含むブックマーク

Ruby on RailsJavaScript との連係が思ったよりも弱いらしい。JavaScript は頑張っといて損じゃないって知ってホッとした。

デバッガ 22:40  デバッガ - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p151-153

デバッガの起動は ruby -r debug hoge.rb みたいな。

-r って何だ?

$ ruby --help
~ snip ~
-rlibrary       require the library, before executing your script
~ sinp ~

ほほぉ。て事は。

irb(main):001:0> require 'debug'
Debug.rb
Emacs support available.

/usr/lib/ruby/1.8/irb/context.rb:163:
(rdb:1) /usr/lib/ruby/1.8/irb.rb:151:
(rdb:1) => true

おおー、デバッグモードになった。/usr/lib/ruby/1.8/debug.rb っていうファイルも発見。なるほど。

irb 22:49  irb - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p154-155

おっとぉ、我等が irb の解説も入ってるとは。

サブセッションとかあるのかー、fg で往復出来るんだなー 、こりゃ便利。

エディタ 22:56  エディタ - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p156

Emacs! Emacs!!

くっそー、この著者は Emacs 使いか。vim の場合は良く分からんなー。選択文字列の処理が実行できたらすげぇ便利そうだ。→ それプラギンで出来るんじゃね?

いやいや何かあるでしょう。あとで調べる。

→ 調べたっていうよりも、訳注に書いてあった。

visual モードで選択して : を押してから

w !ruby

で出来た。超便利。

第一部読了 23:09  第一部読了 - 只今Ruby勉強中 を含むブックマーク

うーん、これで一通り簡単なプログラムは組めるようになった感じ。少なくともPHPよりは使えるようになったような気がする。

なんかあったらなるべく Ruby を使うようにしていきたい。とりあえずワンライナーでうまく使えるように練習しよう。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060829

2006-08-27 (Sun)

LL Ring のレポートは 17:06  LL Ring のレポートは - 只今Ruby勉強中 を含むブックマーク

本サイト(?)に書いた。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060827

2006-08-26 (Sat)

00:15  今 - 只今Ruby勉強中 を含むブックマーク

帰って来たので、今日はもう寝る。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060826

2006-08-25 (Fri)

明日は 23:43  明日は - 只今Ruby勉強中 を含むブックマーク

LL Ring なのであとで寝る。 → 寝た

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060825

2006-08-24 (Thu)

js 23:17  js - 只今Ruby勉強中 を含むブックマーク

Javascript がセミコロン使わないでも書けるようになれば良いのに。あと Perl も。

子プロセス 23:24  子プロセス - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p148

(pig とグラフで遊んでたら大分差が開いた。)

子プロセスの終了を待って実行するプログラムの例。サンプル通りに実行してみる。

irb(main):001:0> trap("CLD") {
irb(main):002:1* pid = Process.wait
irb(main):003:1> puts "Child pid #{pid}: terminated"
irb(main):004:1> exit
irb(main):005:1> }
=> nil
irb(main):006:0> exec('sleep 3') if fork == nil
=> nil
irb(main):007:0> Child pid 28189: terminated

fork

これだけじゃ良くわからんので、色々テストして遊んでみる事にする。

例えばこんな感じで実行すると。

puts 'start'

sleep 5 if fork == nil

puts 'waiting...'
Process.wait
puts 'done'

エラーになってしまう。

start
waiting...
waiting...
my.rb:15:in `wait': No child processes (Errno::ECHILD)
        from my.rb:15
done

fork したプロセスが sleep 以降も実行してるって感じか?

子プロセスを終わらせると期待通りに動く。

puts 'start'

if fork == nil
   sleep 5
   exit
end

puts 'waiting...'
Process.wait
puts 'done'

実行。

start
waiting...
done

sleep の所を exec('sleep 5') とかでやると exit しなくても平気。

puts 'start'

if fork == nil
   exec('sleep 3')
end

puts 'waiting...'
Process.wait
puts 'done'

それならと。

puts 'start'

if fork == nil
   puts 'fork'
   exec('sleep 3')
   puts 'fork'
end

puts 'waiting...'
Process.wait
puts 'done'

これを実行すると。

start
fork1
waiting...
done

こうなった。

動きは理解出来た、と思う。


fork なブロック 23:52  fork なブロック - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p149

とりあえずお約束。

irb(main):001:0> IO.popen("date") { |f| puts f.gets }
2006824日 木曜日 23:46:13 JST
=> nil

LANG はシェルの環境変数を引き継いでんだね。

で、fork のブロックのサンプルコード。

fork do
   puts "In child, pid = #$$"
   exit 99
end

pid = Process.wait
puts "Child terminated, pid = #{pid}, exit code = #{$? >> 8}"

なーんだ、さっき散々悩んだのにこのページで答えがほぼ出てるし。fork do はわかりやすくて良い。

そんで実行結果。

In child, pid = 28794
Child terminated, pid = 28794, exit code = 99

ついで

fork do の場合は exit しなくても平気。

fork do
   puts "In child, pid = #$$"
end

pid = Process.wait
puts "Child terminated, pid = #{pid}, exit code = #{$? >> 8}"

実行。

In child, pid = 28864
Child terminated, pid = 28864, exit code = 0
トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060824

2006-08-23 (Wed)

spamcheck のリファクタ 23:54  spamcheck のリファクタ - 只今Ruby勉強中 を含むブックマーク

昨日 の続き。全然 Ruby っぽくない!!

#! /usr/bin/env ruby

dir = ARGV.to_s.sub(/\/$/, '')

if dir == '' or !FileTest.directory?(dir)
   puts "usage: [dir]\n"
   exit 1
end

require 'date'
require 'mailread'

days = {}

Dir::glob(dir + '/**/*', File::FNM_DOTMATCH).each do |file|
   next if FileTest.directory?(file)

   mail = Mail.new(file)
   date = mail['date']

   unless date
      print 'error: ', file , "\n"
      next
   end

   d = Date.parse(date)
   days[d] = days[d] ? days[d] + 1 : 1
end

days.sort.each do |k, v|
   print k, ' => ', '*' * v, "\n"
end

昨日、Mail クラスがヘッダの大文字小文字を区別してて嫌だ、とか書いたけど勘違いでして、Mail#header とか使わないでもアクセス出来た。たまたま mailread.rb 読んでみたら凄く短いスクリプトだったからすぐわかった。

ディレクトリリストを走査するやつも発見出来た。今回探査するディレクトリの中にドットで始まるディレクトリ名がいっぱいあったので、これに対する対応を調べるのに手間取った。詳細は refe File fnmatch で。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060823

2006-08-22 (Tue)

ボクならこう書く 00:37  ボクならこう書く - 只今Ruby勉強中 を含むブックマーク

LL Ringブログでやってる「キミならどう書く」シリーズで、何でも良いからグラフを作ってみやがれって言うお題があったのでおもしろそうだからチャレンジしてみました。

そういえば以前、いやな人スパムメールの件数をグラフにしてたなーって思ったので、それをやってみる事にしました。

まぁとりあえずほとんどベタ書きで。

dir = ARGV.to_s

require 'date'
require 'mailread'

class MyMail < Mail
   def header
      MailHeader.new(super)
   end
end

class MailHeader
   def initialize(header)
      @headers = {}
      header.each do |k, v|
         @headers[k.downcase] = v
      end
   end

   def [](attr)
      @headers[attr.downcase]
   end
end

def Dirs(dir)
   lists = []

   Dir.open(dir).each do |file|
      next if file =~ /^\.\./
      next if file =~ /^\.$/
      file = dir + '/' + file

      if FileTest.directory?(file)
         lists = lists + Dirs(file)
      else
         lists.push(file)
      end
   end

   return lists
end

days = {}

lists = Dirs(dir)

lists.each do |file|
   mail = MyMail.new(file.to_s)
   h = mail.header
   begin
      d = Date.parse(h['date'])
   rescue
      print 'error:', file, "\n"
      next
   end
   days[d] = 0 unless days[d]
   days[d] += 1
end

days.sort.each do |k, v|
   print k, ' => ', '*' * v, "\n"
end

まず Mail クラスの存在に気付くのが遅れた。メールの解析用のクラスを作ってたら、標準で Mail クラスがあるっぽい事がわかって急遽そっちに移行。つか refeMail を調べると「シンプルなメールクラス」とかって解説が出て来ていかにも使えそうな感じを出してるのに mailread の事がどこにも書いてなくて結局ぐぐってしまった。なんか良い調べ方はあるんでしょうか?後半の Date クラスも require するファイル名はぐぐって調べたし。まだこの辺の調査にすごく時間がかかる。

Mail クラスがヘッダの読み込みで大文字と小文字を区別してるみたいだったので、その辺の差位を吸収出来るような MyMail クラスってのを作ってみました。@headers をもうちょっと綺麗に生成したい所。 → あとで調べる → これで十分ぽい。

ファイルリストを読み込む Dirs の配列の処理ではまった。最初 lists.push(Dirs(file)) で配列を合体させていたつもりだったんだけど、これが駄目って事になかなか気付けなかった。ていうかそもそもファイルリストをゲットしてくれるクラスとかありそうな予感。→ あとで調べる → 調べた

Date.parse が失敗した時の処理方法をうまくやる方法がわからなかった。メールじゃないファイルもいくつか入ってるので、そこでエラーになっちゃう。ひとまず例外の捕捉とかを試してみた。あ、h['date'] が失敗したら next すりゃいいのか…。

そんで、実行結果のうちから7月分だけ出して来た。

2006-07-01 => **********************************************************
2006-07-02 => ***********************************************************
2006-07-03 => ********************************************************
2006-07-04 => ************************************************************************
2006-07-05 => *******************************************************
2006-07-06 => ***************************************************************
2006-07-07 => ***********************************************
2006-07-08 => ****************************************************
2006-07-09 => *********************************************************
2006-07-10 => **************************************
2006-07-11 => ****************************************************
2006-07-12 => ***************************************************************
2006-07-13 => ************************************************************************************************
2006-07-14 => *******************************************************************************
2006-07-15 => ***************************************************************************
2006-07-16 => **************************************************************************
2006-07-17 => ********************************************************************
2006-07-18 => ***********************************************************************
2006-07-19 => *********************************************************************************************
2006-07-20 => ************************************************************************
2006-07-21 => ***********************************************************************************
2006-07-22 => ******************************************************************************
2006-07-23 => *****************************************************************************
2006-07-24 => ***********************************************************************************************************
2006-07-25 => *************************************************************************
2006-07-26 => *************************************************************************************
2006-07-27 => ***************************************************************
2006-07-28 => ***************************************************************
2006-07-29 => *************************************************************************
2006-07-30 => *****************************************************************
2006-07-31 => *********************************************************************
トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060822

2006-08-21 (Mon)

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060821

2006-08-19 (Sat)

Pig 23:31  Pig - 只今Ruby勉強中 を含むブックマーク

ライバルな人が pig コマンド作っててアルゴリズムが大分違ってびっくり。ランダムじゃないのかぁ。調べてみたんだけど、pig コマンドが発見出来ない。

Wikipedia でそれらしいモノを見つけたけど、英語を使ったゲームっぽい…。

Google にも…。

そういえば、Google の奴は見た事あったような…。

後で読んでちゃんと作ってみようっと。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060819

2006-08-18 (Fri)

piged! 出来た! 23:58  piged! 出来た! - 只今Ruby勉強中 を含むブックマーク

昨日格闘してた pig コマンドが出来た!!

あんま綺麗じゃないけど、こんな感じで。

#! /usr/bin/env ruby

class String
   def piged
      list = self.split(/\s+/)

      res = []

      list.each do |str|
         x = ''
         while str.length > 0 do
            x << str.slice!(rand(str.length), 1)
         end
         res << x + 'ay'
      end

      res.join(' ')
   end

   def piged!
      self.replace(self.piged)
   end
end

puts gets.piged

えー、連続した空白が消えちゃうのは許して。

$ pig
this is a pen
htisay isay aay penay

すげ、おもすれー。

プロセス生成 00:08  プロセス生成 - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p146-147

そんでもってメインのパイプラインの処理。

irb(main):001:0> pig = IO.popen("pig", "w+")
=> #<IO:0x40326960>
irb(main):002:0> pig.puts "ice creeam after they go to bed"
=> nil
irb(main):003:0> pig.close_write
=> nil
irb(main):004:0> puts pig.gets
iceay mecraeay areftay ethyay ogay toay edbay
=> nil

おー、ちゃんと標準入力のリクエストに答えて結果を受け取ってる。感動した、っつかー簡単ね、これ。

そいで今さらながら気が付いたけど、オレが想定してた pig コマンドは誤りがあった。書籍のサンプルだと結果が「iceway eamcray afterway eythay ogay otay edbay」になってるんだけど、ice と after に余分な w が含まれてる。どうでも良いけど。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060818

2006-08-17 (Thu)

条件変数 23:33  条件変数 - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p145

スレッドの取扱について。クリティカルセクションにいて特定のリソースが開放されるのを待ちながら、このスレッドがスリープすると他のスレッドが困ってどうたらこうたら言う話し。クリティカルセクションとかちゃんと理解してないから後で読む。

pig 00:38  pig - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p146-147

子プロセスとやり取りするのにパイプラインでほげる事が簡単に出来るそうで、pig っていうプログラムを例にして解説されていた。pig コマンドは入っていないけど動作は単純そう*1だったから、せっかくなんで ruby で自作してみる事に決まったのですが、1時間かけても出来ないので今日は中止に。

配列をランダムにソートする方法は出来た。

%w( a b c d e ).sort {
   rand(3) - 1
}

String クラスに piged メソッドを追加して self をランダムソートしたいんだがうまくいかない。self を文字単位で配列に変換する方法がわからない or 配列に変換しないでやる最良の方法があるか?後で調べる。

String.chomp! みたいなのは破壊的なメソッドって事で、こいつを自作する場合

class String
   def piged!
      self.replace(self.piged)
   end
end

みたいにして別途 piged を定義してやると良い感じになった。

このリファレンスが参考になった。→ http://ruby256.hp.infoseek.co.jp/ruby-refm.html#label:385

ランダム配列

このスレッドが参考になる。correct と slice を使うと良いっぽい。

上で自分が書いたやつは

hoge.sort_by {
   rand()
}

と言う風により単純に書く事も出来たみたい。

*1:単語中の文字をランダムに並べ換えてから末尾に ay を付けるだけっぽい。"this is a pen" => "ithsay siay aay enpay"

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060817

2006-08-16 (Wed)

スレッドスケジューラ、の制御 00:30  スレッドスケジューラ、の制御 - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p142

Thread.pass とか Thread.stop とか使い方が良く分からん。後でやる。

…、ああ、もしかして手動で停止させて、あとで好きな時に再開出来るって話しか。なるほど。

Mutex 00:42  Mutex - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p143-144

スレッドの動作はアトミックじゃないから外から見た時の状況に一貫性は無いよってお話し。

昨日の スレッドプログラム を irb で走らせたら動作がおかしかったんだけど、これが原因っぽい。

何回やっても、改行位置がずれてしまっていたんですよね…。

10 => sleep 611 => sleep 612 => sleep 6
13 => sleep 4
14 => sleep 3
15 => sleep 3


15 finishd14 finishd

13 finishd
11 finishd10 finishd12 finishd


=> true

Mutex で実行させたら期待通りに動くようになった。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060816

2006-08-15 (Tue)

山へ行きました 23:04  山へ行きました - 只今Ruby勉強中 を含むブックマーク

f:id:gaba:20060814120155j:image:w300

はてなフォトライフを使ってみたかったので、使ってみます。こうなっていたのか。なるほど。どいつもこいつも写真についてるリンクをクリックしても画像のサイズが大きくなんねーよプンスカ!!とか思っていたら、アップロードした時のサイズと小さいサムネイルの画像しか用意されないのね。納得。でもこれは不便じゃないかしら。

スレッド 23:37  スレッド - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p137-138

スレッドおもすれー。プロセスをランダムにスリープするだけの作って。

threads = []

10.upto(15) do |i|
   threads << Thread.new(i) do |num|
      r = rand(10) + 3
      puts "#{num} => sleep #{r}"
      sleep r
      puts "#{num} finishd"
   end
end

threads.each do |t|
   t.join
end

実行。

10 => sleep 4
11 => sleep 12
12 => sleep 7
13 => sleep 11
14 => sleep 9
15 => sleep 5
10 finishd
15 finishd
12 finishd
14 finishd
13 finishd
11 finishd

スレッド変数 23:50  スレッド変数 - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p140-141

うは、スリープさせる例が出てきた。

Thread.current が変数っぽい振る舞いをする、と。スレッド処理とスレッド終了後の処理の処理を分けて書くのが簡単になりそうだね。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060815

2006-08-11 (Fri)

module_function 14:34  module_function - 只今Ruby勉強中 を含むブックマーク

module_function てのを 教えてもらった。

attr_reader とか attr_writer の仲間っぽい。

この前書いた例は、だからこうやると include した時とモジュールメソッドで呼んだ時とで同じ処理になるわけだ。

module Gaba
   module_function

   def name
      "takayama"
   end
end

open-uri 14:38  open-uri - 只今Ruby勉強中 を含むブックマーク

open-uri てのも http://rubyist.g.hatena.ne.jp/gaba/20060809/1155132701#c:title=教えてもらった。

うちの環境だと標準で使えた。

irb(main):001:0> require 'open-uri'
=> true

なんて充実してるんだ!

irb で補完 14:43  irb で補完 - 只今Ruby勉強中 を含むブックマーク

irb で補完が使える事を知った。irb/completion を読み込むだけらしい。早速試した。

require 'irb/completion'

すげぇえ便利げ。

毎回 require するのめんどいなと思っていたら、~/.irbrc に書けば幸せになれる事を知った。irbrc は irb 起動時に実行する ruby のコードを書いておく場所みたい。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060811

2006-08-09 (Wed)

ファイルIO 23:07  ファイルIO - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p129-133

一行ずつ読み込んで処理する。close しなくて良くて楽。

File.open('data.txt').each do |line|
   puts line
end

each_line ていうメソッドもある。こっちはセパレータを指定出来る。例えばカンマ区切り。

File.open('data.txt').each_line(',') do |line|
   puts line
end

ネットワーク 23:11  ネットワーク - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p134-135

標準のモジュールが充実してて便利クサイ。書籍のまんまだけど google に行ってみた。

irb(main):001:0> require 'net/http'
=> true
irb(main):002:0> h = Net::HTTP.new('www.google.co.jp', 80)
=> #<Net::HTTP www.google.co.jp:80 open=false>
irb(main):003:0> resp, data = h.get('/', nil)
=> [#<Net::HTTPOK 200 OK readbody=true>, "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=Shift_JIS\"><title>Go
〜 省略 〜

結果をファイルに書き出してみたり。

irb(main):004:0> File.open('google.txt', 'w') do |f|
irb(main):005:1* f.puts data
irb(main):006:1> end
=> nil

本屋 23:21  本屋 - 只今Ruby勉強中 を含むブックマーク

一番近くの本屋さんはそれほど大きな所ではないから Ruby の本は置いてなくて、Perl と HTML の本は同じ所にまとめてあるくせに PHP はプログラミング言語の本が集まってる棚の方に置いてあって、勿論オライリーなんて高級な本も置いてないし、あぁきっとこの本屋はそっち関連の人間が居ないんだろうなとか思ってたけど、この前、最近出た Rails の本が何種類か置いてあるのを発見しました。うぉー、我が街(?)にも rubyist が!?これから?増える兆候?

secondlifesecondlife2006/08/11 00:51最近だと http からデータ読み込むだけなら open-uri ライブラリが便利です。
require 'open-uri'
puts open('http://www.google.co.jp').read

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060809

2006-08-07 (Mon)

モジュール 00:07  モジュール - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p119-121

気を取り直して再度モジュール。

定数にアクセスする時は :: を使うらしい。じゃ、メソッドは?って事で試した。

irb(main):001:0> module Trig
irb(main):002:1> PI = 3
irb(main):003:1> end
=> 3
irb(main):004:0> Trig.PI
NoMethodError: undefined method `PI' for Trig:Module
        from (irb):4
        from :0
irb(main):005:0> Trig::PI
=> 3
irb(main):006:0> module Trig
irb(main):007:1> def sin
irb(main):008:2> "cos"
irb(main):009:2> end
irb(main):010:1> end
=> nil
irb(main):011:0> Trig.sin
NoMethodError: undefined method `sin' for Trig:Module
        from (irb):11
        from :0
irb(main):012:0> Trig::sin
NoMethodError: undefined method `sin' for Trig:Module
        from (irb):12
        from :0

残念でした、と。

Mixin 00:13  Mixin - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p121-123

あー、なるほど。理解できた。上で書いたやり方は Mixin の際に効果を発揮するやり方ってわけか。はた目から見たらかなりアホな事やってたね。これは。

適当にやってみる。

module Gaba
   def name
      "takayama"
   end

   def Gaba.name
      "Gaba.takayama"
   end
end

class Hoge
   include Gaba
   def initialize
      # ...
   end
   def try
      name
   end
end

てのを作って irb で呼び出し。

irb(main):017:0> h = Hoge.new
=> #<Hoge:0x40301958>
irb(main):018:0> h.try
=> "takayama"
irb(main):019:0> Gaba.name
=> "Gaba.takayama"

うん、期待通り。

ここの Gaba.name ってのはモジュールメソッドって呼び名があるらしい。

Mixin のインスタンス変数 00:24  Mixin のインスタンス変数 - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p124-125

Mixin モジュールの中でもインスタンス変数は定義出来て、呼び出したクラスの中でも使えるよってお話し。でもこれが必要になるんだったら、そのモジュールってクラスになれるんじゃないかなーとか思ってしまった。でも多分確実に勘違いでしょう。

secondlifesecondlife2006/08/11 00:49module_function を使うと外部からでもモジュール内部のメソッドを呼べますよ。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060807

2006-08-06 (Sun)

モジュール 21:39  モジュール - 只今Ruby勉強中 を含むブックマーク

と Mixin 読んだけど全然頭に入らん。Mixin は便利そうだ。

モジュールはメソッド定義の所でフルに名前が書いてあったけど、無くても平気っぽい。何か違いはあるのだろうか。

module Trig
   def sin(x)
      "sin"
   end
   def Trig.sin(x)
      "sin2"
   end
end

結果

irb(main):032:0> Trig.sin(1)
=> "sin2"

Trig.sin を上に持って来ても sin2 が返って来る。Trig.sin を消すと sin が返って来る。優先順位は Trig.sin > sin

追記:

しまった、これすっげえ勘違いだった。Trig.sin の形式じゃないと動かないっぽい。irb の中で外部ファイルを何度もロードさせながらやってたから勘違いしてしまった。

ensure の追加 21:46  ensure の追加 - 只今Ruby勉強中 を含むブックマーク

この前の ensureいらなくね? にまた反応がありました。ありがたいです。

なるほど、File.open以前教えてもらった ブロックで File.open するやり方だと close しなくても良いって言うのは内部で ensure が使われていそうですね。

勉強になります。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060806

2006-08-05 (Sat)

ensure 12:55  ensure - 只今Ruby勉強中 を含むブックマーク

おととい ensureいらなくね? って言ったら、突っ込みして教えてもらえました!わーいわーい。

end 以降が実行される保証なんて無いから、必ずやりたい後処理は ensure でやれって事ですね。納得。そう考えると書籍に書いてあったように else は使い所がなさそうな予感。ほぉー、なるほどなるほど。

お二人ともどうもありがとうございました。

コメント 13:14  コメント - 只今Ruby勉強中 を含むブックマーク

って id:gaba さんって鷹の島の中の人だったのか!

'hceT'.sub(/\Z/,'bus').reverse - ensure

gaba って絶対わかりにくいからサブアカ取ったりしようと思った事もあったけど、なんか良い名前が思い浮かばないから放置中でして、でもやっぱ考えておいた方が良いのかなぁと思いました。

もうちょっと一通りの事が出来るようになったら rails のソース読んで DHH 神のセンスに触れてみたいと考えてますよ、オレ、センスないからセンス磨きは重要な使命なの!やっぱプログラマにはセンスが大事でしょ、うん。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060805

2006-08-04 (Fri)

読んだ 22:59  読んだ - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p114-117

まで読んだ、だけ。今日は気分が乗ってない感じ。

例外はまた後でやる。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060804

2006-08-03 (Thu)

同じトコでつまってますね 00:58  同じトコでつまってますね - 只今Ruby勉強中 を含むブックマーク

これはヤバイ。もっとコードを書いて頑張れって言うお告げがあった。:-)

例外 01:10  例外 - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p109-112

eval で hoge を実行しようとしてエラー。

irb(main):032:0> string = 'hoge'
=> "hoge"
irb(main):033:0> begin
irb(main):034:1* eval string
irb(main):035:1> rescue SyntaxError, NameError => boom
irb(main):036:1> print "String doesn't compile: " + boom
irb(main):037:1> rescue StandardError => bang
irb(main):038:1>
irb(main):039:1* print "Error running script: " +bang
irb(main):040:1> end
Error running script: (eval):1:in `hoge': wrong number of arguments (0 for 1)=> nil

begin が開始はわかりにくいかもなー。SyntaxError はどうやって発生させるんだろう?

て言うか告白すると、例外処理って今まで全然ちゃんとやってないからこの機会にしっかり学ばなくては。

良くみたら最初に試したコードで出てたよ、SyntaxError

irb(main):024:0> begin
irb(main):025:1* eval string
irb(main):026:1> rescue SyntaxError, NameError => boom
irb(main):027:1> print "String doesn't compile: " + boom
irb(main):028:1> rescue StandardError => bang
irb(main):029:1> print "Error running script: " +bang
irb(main):030:1> end
String doesn't compile: undefined local variable or method `string' for main:Object=> nil

これは、eval すら実行出来なかった、って事かな。

実例 01:10  実例 - 只今Ruby勉強中 を含むブックマーク

と、いつもこんな風に書籍のコピペをしてるだけでして…。

ensure, else 01:20  ensure, else - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p113

  • ensure - 例外が発生しようがなかろうが必ず実行されるブロック
  • else - 例外が発生しなかった場合に実行されるブロック
begin
   # 処理
rescure ...
   # 例外発生時
else
   # 例外がなくて良かった
ensure
   # 必ず実行
end

書籍に else はあまり役に立ちませんとか書いてあったけど、ensure の方がいらなくね? end の後ろに書いておけばヨクネ? とか思うのはオレが例外初心者だからでしょうか。

2006-08-01 (Tue)

while 01:00  while - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p101

どうしてもわからない。

これは期待通りに動くんだけど。

while file.gets
   print if $. == 2 .. $. == 5
end

こっちが出来ない…、のは ruby1.8 だから?

while file.gets
   print if /load/ .. /self/
end

前にも同じ事やった んだよね。

ループ 01:09  ループ - 只今Ruby勉強中 を含むブックマーク

うさぎ本: p102-107

メモ

  • while, until, for の中だけで使うローカル変数は定義出来ない。
  • each 内で作成された変数はローカル変数になる。だけど外で同名の変数を使っていたらローカルにはならない。
  • ループは break, redo, next, retry を使って制御出来る。
  • for と each を使い分けられるようになればループマスターになれる。

こっそりとライバル 01:13  こっそりとライバル - 只今Ruby勉強中 を含むブックマーク

丁度同時期にうさぎ本を読み始めた方を発見したからずっとこっそりヲチしてたんだけど、ちょっとずつ差が開いて来てヤバい。もっと頑張らないと。

こう、自分のちょっと先を淡々と進んでいるので、凄く励みになります。

トラックバック - http://rubyist.g.hatena.ne.jp/gaba/20060801