print("Hello, Ruby.\n")
puts "Hello,\n\tRuby." p "Hello,\n\tRuby."
print "いづれの御時にか女御更衣あまたさぶらいたまいけるなかに\n" print "いとやむごとなき際にはあらぬがすぐれて時めきたまふありけり\n"
x = 10 y = 20 z = 30 area = (x*y + y*z + z*x) * 2 volume = x * y * z print "表面積=", area, "\n" print "体積=", volume, "\n"
=begin 「たのしいRuby 第3版」サンプル コメントの使い方の例 2006/06/16 作成 2006/07/01 一部コメントを追加 2009/11/01 第3版用に更新 =end x = 10 # 横 y = 20 # 縦 z = 30 # 高さ # 表面積と体積を計算する area = (x*y + y*z + z*x) * 2 volume = x * y * z # 出力する print "表面積=", area, "\n" print "体積=", volume, "\n"
a = 20 if a >= 10 then print "bigger\n" end if a <= 9 then print "smaller\n" end
def hello print "Hello, Ruby\n" end hello()
def hello print "Hello, Ruby.\n" end
require "hello" # hello.rbの読み込み(「.rb」は必要ない) hello() # helloメソッドの起動
print "<html><title>font size list</title>" print "<body>\n<p>\n" font_table = {:normal => "+0", :small => "-1", :big => "+1"} font_table.each do |key, value| print '<font size="', value, '">',key,'</font><br>',"\n" end print "</p></body></html>\n"
names = ["小林", "林", "高野", "森岡"] names.each do |name| if /林/ =~ name puts name end end
require "pp" v = [ { :key_00 => "「たのしいRuby」", :key_01 => "「Rubyレシピブック」", :key_02 => "「Railsレシピブック」", :key_03 => "「たのしいRuby 第3版」", } ] p v pp v
print "最初の引数: ", ARGV[0], "\n" print "2番目の引数: ", ARGV[1], "\n" print "3番目の引数: ", ARGV[2], "\n"
name = ARGV[0] print "Happy Birthday, ", name, "!\n"
num0 = ARGV[0].to_i num1 = ARGV[1].to_i print num0, " + ", num1, " = ", num0 + num1, "\n" print num0, " - ", num1, " = ", num0 - num1, "\n" print num0, " * ", num1, " = ", num0 * num1, "\n" print num0, " / ", num1, " = ", num0 / num1, "\n"
filename = ARGV[0] file = open(filename) text = file.read print text file.close
filename = ARGV[0] text = File.read(filename) print text
print File.read(ARGV[0])
filename = ARGV[0] file = open(filename) while text = file.gets print text end file.close
pattern = Regexp.new(ARGV[0]) filename = ARGV[1] 3: file = open(filename) while text = file.gets if pattern =~ text print text end end file.close
$x = 0 x = 0 require "sub" p $x #=> 1 p x #=> 0
$x = 1 ## グローバル変数に代入 x = 1 ## ローカル変数に代入
# 西暦から平成に変換する ad = ARGV[0].to_i heisei = ad - 1988 print heisei,"\n"
a = 10 b = 20 if b > a print "bはaよりも大きい\n" elsif b == a print "bはaと同じ\n" else print "aよりも小さい\n" end
a = 10 b = 20 unless a > b print "aはbより大きくない\n" end
tags = [ "A", "IMG", "PRE" ] tags.each do |tagname| case tagname when "P","A","I","B","BLOCKQUOTE" print tagname, " has child.\n" when "IMG", "BR" print tagname, " has no child.\n" else print tagname, " cannot be used.\n" end end
array = [ "a", 1, nil ] array.each do |item| case item when String puts "item is a String." when Numeric puts "item is a Numeric." else puts "item is something." end end
4.times do print "いちめんのなのはな\n" end
5.times do |i| print i,"回目の繰り返しです。\n" end
5.times do |i| print i+1,"回目の繰り返しです。\n" end
sum = 0 for i in 1..5 sum = sum + i end print sum,"\n"
names = ["awk", "Perl", "Python", "Ruby"] for name in names print name,"\n" end
i = 1 while i<3 print i,"\n" i+=1 end
sum = 0 i = 1 while i <= 5 sum += i i += 1 end print sum,"\n"
sum = 0 i = 1 while sum < 50 sum += i i += 1 end print sum,"\n"
sum = 0 i = 1 until sum>=50 sum += i i += 1 end print sum, "\n"
sum = 0 i = 1 while !(sum >= 50) sum += i i += 1 end print sum, "\n"
names = ["awk","Perl","Python","Ruby"] names.each do |name| print name,"\n" end
sum = 0 (1..5).each do |i| sum = sum + i end print sum,"\n"
print "breakの例:\n" i = 0 ["Perl", "Python", "Ruby", "Scheme"].each do |lang| i += 1 if i == 3 break end p [ i, lang ] end 10: print "\nnextの例:\n" i = 0 ["Perl", "Python", "Ruby", "Scheme"].each do |lang| i += 1 if i == 3 next end p [ i, lang ] end 20: print "\nredoの例:\n" i = 0 ["Perl", "Python", "Ruby", "Scheme"].each do |lang| i += 1 if i == 3 redo end p [ i, lang ] end
pattern = Regexp.new(ARGV[0]) filename = ARGV[1] max_matches = 10 # 出力する最大数 matches = 0 # マッチした行数 file = open(filename) while text = file.gets if matches >= max_matches break end if pattern =~ text matches += 1 print text end end
file = open(ARGV[0]) while text = file.gets next if /^\s*$/ =~ text # 空白行 next if /^#/ =~ text # シャープで始まる行 print text end
# 10の階乗を求める ans = 1 for i in 1..10 ans *= i end # 出力する print "10! = ", ans, "\n"
ans = 1 for i in 1..10 ans *= i end print "10! = ", ans, "\n"
def hello(name) print("Hello, ", name, ".\n") end hello("Ruby")
def hello(name="Ruby") print("Hello, ", name, ".\n") end hello() # 引数を省略して呼び出す hello("Newbie") # 引数を指定して呼び出す
class HelloWorld # class文 Version = "1.0" # 定数の定義 def initialize(myname="Ruby") # initializeメソッド @name = myname # インスタンス変数の初期化 end def hello # インスタンスメソッド print "Hello, world. I am ", @name, ".\n" end end bob = HelloWorld.new("Bob") alice = HelloWorld.new("Alice") ruby = HelloWorld.new bob.hello
class HelloCount @@count = 0 # helloメソッドの呼び出し回数 def HelloCount.count # 呼び出し回数を参照するためのクラスメソッド @@count end def initialize(myname="Ruby") @name = myname end def hello @@count += 1 # 呼び出し回数を加算する print "Hello, world. I am ", @name, ".\n" end end bob = HelloCount.new("Bob") alice = HelloCount.new("Alice") ruby = HelloCount.new p HelloCount.count #=> 0 bob.hello alice.hello ruby.hello p HelloCount.count #=> 3
class String def count_word ary = self.split(/\s+/) # 自分自身を空白文字で分解する return ary.size # 分解後の配列の要素数を返す end end str = "Just Another Ruby Newbie" p str.count_word #=> 4
class AccTest def pub puts "pub is a public method." end public :pub # pubメソッドをpublicに設定(指定しなくてもよい) def priv puts "priv is a private method." end private :priv # privメソッドをprivateに設定 end acc = AccTest.new acc.pub #=> pub is a public method. acc.priv #=> エラー
class Point attr_accessor :x, :y # アクセスメソッドを定義する protected :x=, :y= # x=とy=をprotectedにする def initialize(x=0.0, y=0.0) @x, @y = x, y end def swap(other) # x, yの値を入れ換えるメソッド tmp_x, tmp_y = @x, @y @x, @y = other.x, other.y other.x, other.y = tmp_x, tmp_y # 同一クラス内では呼び出すことができる return self end end p0 = Point.new p1 = Point.new(1.0, 2.0) p [ p0.x, p0.y ] #=> [0.0, 0.0] p [ p1.x, p1.y ] #=> [1.0, 2.0] p0.swap(p1) p [ p0.x, p0.y ] #=> [1.0, 2.0] p [ p1.x, p1.y ] #=> [0.0, 0.0] p0.x = 10.0 #=> エラー
ring_array.rb class RingArray < Array # スーパークラスを指定する def [](i) # 演算子[]の再定義 idx = i % size # 新しいインデックスを求める super(idx) # スーパークラスの同名のメソッドを呼ぶ end end eto = RingArray[ "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" ] p eto[6] #=> "午" p eto[11] #=> "亥" p eto[15] #=> "卯" p eto[-1] #=> "亥"
module MyModule # 共通して提供したいメソッドなど end class MyClass1 include MyModule # MyClass1 に固有のメソッドなど end class MyClass2 include MyModule # MyClass2 に固有のメソッドなど end
module HelloModule # module文 Version = "1.0" # 定数の定義 def hello(name) # メソッドの定義 print "Hello, ", name, ".\n" end module_function :hello # helloをモジュール関数として公開する end p HelloModule::Version #=> "1.0" HelloModule.hello("Alice") #=> Hello, Alice. include HelloModule # インクルードしてみる p Version #=> "1.0" hello("Alice") #=> Hello, Alice.
def fetch_and_downcase(ary, index) if str = ary[index] return str.downcase end end ary = ["Boo", "Foo", "Woo"] p fetch_and_downcase(ary, 1) #=> "foo"
require "net/http" url = URI.parse("http://www.ruby-lang.org/ja/") http = Net::HTTP.start(url.host, url.port) doc = http.get(url.path) puts doc
ltotal = 0 # 行数の合計 wtotal = 0 # 単語数の合計 ctotal = 0 # 文字数の合計 ARGV.each do |file| begin input = open(file) # ファイルを開く(A) l = 0 # file内の行数 w = 0 # file内の単語数 c = 0 # file内の文字数 while line = input.gets l += 1 c += line.size line.sub!(/^\s+/, "") # 行頭の空白を削除 ary = line.split(/\s+/) # 空白文字で分解する w += ary.size end input.close # ファイルを閉じる printf("%8d %8d %8d %s\n", l, w, c, file) # 出力を整形する ltotal += l wtotal += w ctotal += c rescue => ex print ex.message, "\n" # 例外のメッセージを出力(B) end end printf("%8d %8d %8d %s\n", ltotal, wtotal, ctotal, "total")
def test_throw throw :test end puts "test start" catch(:test) do puts "before test_throw()" test_throw() puts "after test_throw()" end puts "test end"
ファイル名のあるソースコードはありません。
list = ["a", "b", "c", "d"] for i in 0..3 print i+1,"番目の要素は",list[i],"です。\n" end
list = [1, 3, 5, 7, 9] sum = 0 for i in 0..4 sum += list[i] end print "合計:",sum,"\n"
list = [1, 3, 5, 7, 9] sum = 0 list.each do |elem| sum += elem end print "合計:",sum,"\n"
list = ["a", "b", "c", "d"] list.each_with_index do |elem, i| print i+1,"番目の要素は",elem,"です。\n" end
ary1 = [1, 2, 3, 4, 5] ary2 = [10, 20, 30, 40, 50] ary3 = [100, 200, 300, 400, 500] i = 0 result = [] while i < ary1.length result << ary1[i] + ary2[i] + ary3[i] i += 1 end p result #=> [111, 222, 333, 444, 555]
ary1 = [1, 2, 3, 4, 5] ary2 = [10, 20, 30, 40, 50] ary3 = [100, 200, 300, 400, 500] result = [] ary1.zip(ary2, ary3) do |a, b, c| result << a + b + c end p result #=> [111, 222, 333, 444, 555]
ファイル名のあるソースコードはありません。
# 単語数のカウント 2: count = Hash.new(0) 4: ## 単語の集計 while line = gets words = line.split words.each do |word| count[word] += 1 end end 12: ## 結果の出力 count.sort{|(k1,v1), (k2,v2)| v1 <=> v2}.each do |key, value| print "#{key}: #{value}\n" end
"abracatabra".scan(/.a/) do |matched| p matched end
"abracatabra".scan(/(.)(a)/) do |matched| p matched end
"abracatabra".scan(/(.)(a)/) do |a, b| p a+"-"+b end
str = "http://www.ruby-lang.org/ja/" %r|http://([^/]*)/| =~ str print "server address: ", $1, "\n"
$stdout.print "Output to $stdout.\n" # 標準出力 $stderr.print "Output to $stderr.\n" # 標準エラー出力
if $stdin.tty? print "Stdin is a TTY.\n" else print "Stdin is not a TTY.\n" end
require "open-uri" # HTTP経由でデータを読み込む open("http://www.ruby-lang.org") do |io| puts io.read # Rubyのホームページをコンソールに出力する end # FTP経由でデータを読み込む open("ftp://www.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7.tar.gz") do |io| open("ruby-1.8.7.tar.gz", "w") do |f| # ローカルファイルを開く f.write(io.read) end end
require "open-uri" options = { "Accept-Language" => "ja, en;q=0.5", } open("http://www.ruby-lang.org", options){|io| puts io.read }
require "stringio" io = StringIO.new io.puts("A") io.puts("B") io.puts("C") io.rewind p io.read #=> "A\nB\nC\n"
require "stringio" io = StringIO.new("A\nB\nC\n") p io.gets #=> "A\n" p io.gets #=> "B\n" p io.gets #=> "C\n"
$stdout.puts "foo", "bar", "baz"
$stdout.putc(82) # 82は「R」のASCIIコード $stdout.putc(?R) $stdout.putc("\n")
$stdout.print "out1 " $stderr.print "err1 " $stdout.print "out2 " $stdout.print "out3 " $stderr.print "err2\n" $stdout.print "out4\n"
$stdout.print "out1 "; $stdout.flush $stderr.print "err1 " $stdout.print "out2 "; $stdout.flush $stdout.print "out3 "; $stdout.flush $stderr.print "err2\n" $stdout.print "out4\n"
$stdout.sync = true # 出力の同期を取る $stdout.print "out1 " $stderr.print "err1 " $stdout.print "out2 " $stdout.print "out3 " $stderr.print "err2\n" $stdout.print "out4\n"
pattern = Regexp.new(ARGV[0]) filename = ARGV[1] if /.gz$/ =~ filename file = IO.popen("gunzip -c #{filename}") else file = File.open(filename) end while text = file.gets do if pattern =~ text print text end end
def traverse(path) if FileTest.directory?(path) # ディレクトリの場合 dir = Dir.open(path) while name = dir.read next if name == "." # ※ next if name == ".." # ※ traverse(path + "/" + name) end dir.close else process_file(path) # ファイルに対する処理 end end def process_file(path) puts path # ひとまず出力するだけ end traverse(ARGV[0])
def traverse(path) Dir.glob(["#{path}/**/*", "#{path}/**/.*"]).each do |name| unless FileTest.directory?(name) process_file(name) end end end
require 'find' IGNORES = [ /^\./, /^CVS$/, /^RCS$/ ] def listdir(top) Find.find(top) do |path| if FileTest.directory?(path) # pathがディレクトリならば dir, base = File.split(path) IGNORES.each do |re| if re =~ base # 無視したいディレクトリの場合 Find.prune # それ以下の検索を省略する end end puts path # 出力する end end end listdir(ARGV[0])
ファイル名のあるソースコードはありません。
puts "$foo: #{$foo}" puts "$bar: #{$bar}" puts "$baz: #{$baz}"
class WarningTest def initialize @test = "test." end def test print @tset,"\n" ##「@test」を「@tset」と書いている! end end sample_test = WarningTest.new sample_test.test
dirlist = `dir` dirlist.each{|line| if line =~ /.rb$/i print line end }
data = DATA.read print data __END__ ここに書かれている文字は,スクリプトとして解釈 されずに,そのままデータとして使用されます。
# クラスの定義 class Foo def initialize puts "foo!!" end end if __FILE__ == $0 Foo.new # サンプルコード end
hash = {:a=>100, :b=>200, :c=>300} hash.each_with_index do |(key, value), index| p [key, value, index] end
var = 1 # ファイル内のvar class Foo var = 2 # クラス定義内のvar def meth var = 3 # メソッド定義内のvar end end === ローカル変数の初期化 ローカル変数は,最初に代入されたときに初期化されます。初期化されていないローカル変数を参照しようとすると例外(NameError)が発生します。 //cmd{ > 【ruby -e 'puts a'】 -e:1: undefined local variable or method `a' for main:Object (NameError)
def local_scope_test(n) if n > 0 positive = true elsif n < 0 negative = true else zero = true end return [positive, negative, zero] end p local_scope_test(1) p local_scope_test(0) p local_scope_test(-1)
x = 1 # xを初期化 ary = [1, 2, 3] ary.each do |x| # ブロック変数としてxを使用する # … end p x # xの値を確認する
x = y = z = 0 # xとyとzを初期化 ary = [1, 2, 3] ary.each do |x; y| # ブロック変数x,ブロックローカル変数yを使用 y = x # ブロックローカルyを代入 z = x # ブロックローカルでないzを代入 p [x, y, z] # ブロック内のxとyの値を確認する end p [x, y, z] # xとyの値を確認する
class Vector attr_reader :x, :y def initialize(x=0, y=0) @x, @y = x, y end def inspect # 表示用 "(#{@x}, #{@y})" end def +(other) Vector.new(@x + other.x, @y + other.y) # x, y のそれぞれを足す end def -(other) Vector.new(@x - other.x, @y - other.y) # x, y のそれぞれを引く end end vec0 = Vector.new(3, 6) vec1 = Vector.new(1, 8) p vec0 #=> (3, 6) p vec1 #=> (1, 8) p vec0 + vec1 #=> (4, 14) p vec0 - vec1 #=> (2, -2)
5.times do print "<br>\n" end
print "<br>\n" print "<br>\n" print "<br>\n" print "<br>\n" print "<br>\n"
sum = 0 (1..5).each do |i| sum += i end print "合計: ",sum,"\n"
sum = 0 sum += 1 sum += 2 sum += 3 sum += 4 sum += 5 print "合計: ",sum,"\n"
fruits = ['リンゴ', 'バナナ', 'パイナップル'] fruits.each do |elem| print elem,"\n" end
sum = 0 outcome = {"参加費"=>1000, "ストラップ代"=>1000,"懇親会会費"=>4000} outcome.each do |item, price| sum += price end print "合計: ",sum,"\n"
sum = 0 outcome = {"参加費"=>1000, "ストラップ代"=>1000,"懇親会会費"=>4000} outcome.each do |pair| sum += pair[1] # 値を指定している end print "合計: ",sum,"\n"
f = File.open("sample.txt") f.each do |line| print line end f.close
File.open("sample.txt") do |f| f.each_line do |line| print line end end
class Book attr_accessor :title, :author, :genre def initialize(title, author, genre=nil) @title = title @author = author @genre = genre end end
require 'book' class BookList ## 初期化 def initialize() @booklist = Array.new end ## 新しい本を加える def add(book) @booklist.push(book) end ## 本の冊数を返す def length @booklist.length end ## n番目に格納されている本を別の本にする def []=(n,book) @booklist[n] = book end ## n番目に格納されている本を返す def [](n) @booklist[n] end ## 本をリストから削除する def delete(book) @booklist.delete(book) end end
require 'book' require 'booklist' # 本のリストを作る。最初はリストは空になる booklist = BookList.new # リストに挿入したい本を用意する b1 = Book.new("せめて,本格らしく","城平京") b2 = Book.new("Neo Aqua III","Neo Aqua") # リストに本を追加する booklist.add(b1) booklist.add(b2) # リストの本を出力する print booklist[0].title, "\n" print booklist[1].title, "\n"
pr = Proc.new{ p "a" } p "b" pr.call()
def foo(a, b, &block) block.call(a, b) end foo("a1", "b1"){|a, b| p a p b }
class Book include Comparable def <=>(other) t = @genre.to_s <=> other.genre.to_s # ジャンルを比較する return t if t != 0 # 違うジャンルならそのまま返す return @title <=> other.title # タイトルを比較した結果を返す end attr_accessor :title, :author, :genre def initialize(title, author, genre=nil) @title = title @author = author @genre = genre end end
require 'book_cmp' ary = [] ary << Book.new("Software", "Rucker", "SF") ary << Book.new("BABEL-17", "Delany", "SF") ary << Book.new("Programming Perl", "Wall", "Computer") ary << Book.new("Programming Pearls", "Bentley", "Computer") ary.sort.each{|book| printf "%-10s %-20s %s\n", book.genre, book.title, book.author }
require "booklist" class BookList include Enumerable def each @booklist.each{|book| yield(book) } end end
require "booklist_enum" booklist = BookList.new booklist.add(Book.new("Software", "Rucker", "SF")) booklist.add(Book.new("BABEL-17", "Delany", "SF")) booklist.add(Book.new("Programming Perl", "Wall", "Computer")) booklist.add(Book.new("Programming Pearls", "Bentley", "Computer")) titles = booklist.collect{|book| book.title } p titles
require 'open-uri' open("http://www.ruby-lang.org/ja/") do |f| 5.times do print f.gets end end
require 'rubygems' require 'open-uri' require 'nokogiri' doc = Nokogiri::HTML(open("http://www.ruby-lang.org/ja/"),nil,'utf-8') doc.css('h3').each do |h3| puts h3.text end
require 'rubygems' require 'open-uri' require 'nokogiri' filename = ARGV[0] doc = Nokogiri::HTML(open(filename),nil, 'utf-8') doc.css('h3').each do |h3| puts h3.text end
require 'rubygems' require 'open-uri' require 'nokogiri' filename = ARGV[0] doc = Nokogiri::HTML(open(filename),nil,'utf-8') doc.css('a').each do |a| url = URI.parse(a["href"]) if url.host puts "#{a.text}:#{a["href"]}" end end
require 'rss' url = 'http://www.ruby-lang.org/ja/feeds/news.rss' rss = RSS::Parser.parse(url) puts rss.channel.title
require 'rss' url = 'http://www.ruby-lang.org/ja/feeds/news.rss' rss = RSS::Parser.parse(url) rss.items.each do |item| print item.pubDate.strftime("%Y/%m/%d"),":",item.title,"\n" end
require 'rubygems' require 'open-uri' require 'nokogiri' require 'rss' filename = ARGV[0] doc = Nokogiri::HTML(open(filename),nil,'utf-8') doc.css('link').each do |link| if link['type'] == 'application/rss+xml' && link['rel'] == 'alternate' href = link['href'] url = URI.join(filename, href) puts "detect: #{url}" rss = RSS::Parser.parse(url) rss.items.each do |item| print item.pubDate.strftime("%Y/%m/%d"),":",item.title,"\n" end end end
文中で使用しているsample-access.logははこちらから取得してください。→sample-access.log
count = 0 # 行数を初期化する File.open(ARGV[0]) do |io| # ファイルを開く io.each_line do |line| # 行ごとに処理する count += 1 # 行数を更新する end end puts count # 行数を表示する
CLF_REGEXP = / \A (?# 行頭) (\S+)\s (?# 1 address) (\S+)\s (?# 2 ident) (\S+)\s (?# 3 user) \[([^\]]+)\]\s (?# 4 time) "(\S+)\s(\S+)\s(\S+)"\s (?# 5 6 7 method url version) (\d+)\s (?# 8 status) (\d+|-)\s (?# 9 bytes) "([^"]*)"\s (?# 10 referer) "([^"]*)" (?# 11 user_agent) \Z (?# 行末) /x count = 0 # 行数を初期化する File.open(ARGV[0]) do |io| # ファイルを開く io.each_line do |line| # 1行ごとに処理する if CLF_REGEXP =~ line # 正規表現にマッチしたら p $~.captures # キャプチャした部分を表示する end count += 1 # 行数を更新する end end puts count # 行数を表示する
module AccessLog CLF_REGEXP = / \A (?# 行頭) (\S+)\s (?# 1 address) (\S+)\s (?# 2 ident) (\S+)\s (?# 3 user) \[([^\]]+)\]\s (?# 4 time) "(\S+)\s(\S+)\s(\S+)"\s (?# 5 6 7 method url version) (\d+)\s (?# 8 status) (\d+|-)\s (?# 9 bytes) "([^"]*)"\s (?# 10 referer) "([^"]*)" (?# 11 user_agent) \Z (?# 行末) /x Entry = Struct.new( # 解析結果を保存するためのクラス :address, :ident, :user, :time, :method, :url, :version, :status, :byte, :referer, :user_agent ) module_function def each_entry(file) file.each_line do |line| if entry = parse(line) yield(entry) end end end def parse(line) if m = CLF_REGEXP.match(line) return Entry.new(*m.captures) end $stderr.puts("parse failure: #{line.dump}") return nil end end
require "access_log" # access_log.rbを読み込む count = 0 File.open(ARGV[0]) do |io| AccessLog.each_entry(io) do |entry| p entry.to_a # エントリを表示する count += 1 end end puts count
require "access_log" entries = [] task :load do logfile = ENV["LOGFILE"] || "access.log" # ログファイル名 puts "loading #{logfile}." # メッセージを表示する File.open(logfile) do |log| # ログファイルを開いて AccessLog.each_entry(log) do |entry| # すべてのエントリを読み込む entries << entry end end end desc "時間帯別のアクセス数を集計する" task :time => :load do hour_count = Hash.new(0) # 集計用のハッシュ entries.each do |entry| # エントリを順に処理する times = entry.time.split(/[:\/ ]/) # 時刻を分割する hour_count[times[3]] += 1 # 「時」のカウントを追加する end hours = hour_count.keys.sort # 「時」の一覧を取得する hours.each do |h| # 集計結果を順に表示する printf("%s: %s\n", h, "#" * (hour_count[h]/3)) end end desc "URL別にアクセス数を集計する" task :url => :load do url_count = Hash.new(0) # 集計用のハッシュ entries.each do |entry| # エントリを順に処理する url_count[entry.url] += 1 # URLのカウントを追加する end ranking = url_count.sort_by{|url, count| -count } # アクセス数の降順になるようにハッシュの要素をソート ranking.each do |url, count| # 集計結果を順に表示する printf("%d: %p\n", count, url) end end desc "エラーになったアクセスを表示する" task :error => :load do entries.each do |entry| # エントリを順に処理する if /^[45]/ =~ entry.status # ステータスが4xxか5xxなら表示する printf("%p %p %p\n", entry.time, entry.status, entry.url) end end end task :default => [:time, :error, :url]