2006-01-01から1ヶ月間の記事一覧

for

範囲を指定してfor文をまわします。x..yは[x, y]で、x...yは[x, y)です。forはメソッドではありません。 for i in 0..9 print "i = #{i}\n" end for i in 0...10 print "i = #{i}\n" end

forと配列

配列を指定してfor文をまわすこともできます。 range = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for i in range print "i = #{i}\n" end

while

Rubyでは、i++は使えません。i += 1と書きます。 i = 0 while i < 10 print "i = #{i}\n" i += 1 end

until

whileに対するuntilは、ifに対するunlessのようなものですね。 i = 0 until 10 <= i print "i = #{i}\n" i += 1 end

each

timesはIntegerのメソッドでしたが、eachはArray(など)のメソッドです。 range = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] range.each { |i| print "i = #{i}\n" }

loopほか

Rubyでは、times, loop, eachはメソッドで、for, while, untilはメソッドではありません。 loop { print "Infinite loop!\n" }

ri -T -w 128

riの出力をページャを通さずに表示するには-Tオプションをつけます。 画面幅を128桁にするには-w 128オプションをつけます。 ri -T -w 128 IO#gets

getsは$_に代入

getsの戻り値は特殊変数$_にも代入されます。getsの戻り値は入力終端でnilになりますから、以下のプログラムで標準入力をすべて標準出力にコピーすることになります。 while gets print $_ end

行頭にclassがある行を検索

標準入力の各行に対して処理を行うというのは基本的なパターンです。行頭にclassがある行を検索してみました。 while line = gets if line =~ /^class/ print $_ end end

環境変数RI

riのオプションは環境変数RIでセットできる set RI=-T -w 128

Time.now

Time.nowは現在日時を返します。Time.newと一字違いですが、やっていることは同じです。 print Time.now

open("| command", "r")

openの第一引数を|で始めるとコマンドを意味します。第二引数が"r"なら実行結果から読み込むことができます。ブロックパラメータはIOオブジェクトです。 open("| dir /s/b", "r") { |file| print file.class, "\n" while line = file.gets print "-- #{line.…

CGI

だいぶ練習できたので、そろそろCGIに挑戦してみます。 #!ruby print <<"EOD" Content-type: text/html <html> <title>Hello</title> <body> <h1>Hello</h1> </body> </html> EOD

CGI.new

CGI.newで得たオブジェクトはハッシュです。与えられたフィールドはcgi.params[フィールド名]で得ることができます。 以下のCGIでは、ユーザが入力した文字列をエスケープせずに出力しますので、XSS脆弱性があります。 #!ruby require "cgi" cgi = CGI.new p…

CGI::escapeHTML

CGI::escapeHTMLメソッドを使うと、HTMLのエスケープが行われます。to_sをつけてから与えないとエラーになってしまいました。おそらくescapeHTMLメソッドに文字列以外を渡してしまうとまずいのでしょう。 疑問 CGI::escapeHTMLとCGI.escapeHTMLはどこが違う…

Stringも拡張できる

Rubyは、組み込みのStringクラスでも拡張できます。debug_printメソッドとtwiceメソッドを追加してみました。 class String def debug_print print "Debug: #{self}\n" return self end def twice return self + self end end p "Hello".debug_print p "Hell…

joinでスレッド待ち

RubyのThread.startはスレッドオブジェクトを返すので、それとjoinすれば起動したスレッドを待つことになります。 Thread.start { 10.times { p Thread.current } }.join Thread.start { 10.times { p Thread.current } }.join実行結果。 #<Thread:0x29470c0 run> #<Thread:0x29470c0 run> #<Thread:0x29470c0 run> #<Thread:0x29470c0 run> #<Thread:0x29470c0 run> #</thread:0x29470c0></thread:0x29470c0></thread:0x29470c0></thread:0x29470c0></thread:0x29470c0>

attr_readerでアクセサ作り

Rubyでは、attr_readerを使うと属性へのアクセサ(ゲッタ)を作れます。以下のプログラムでは@attr1のgetterはありますが、@attr2のgetterはありません。ですからo.attr2でエラーになります。 class Rubyco attr_reader :attr1 def initialize(attr1, attr2)…

flattenとflatten!

Rubyでは、多くの破壊的メソッドに!が付いています。ただし、すべての破壊的メソッドに!がついているわけではありません。 flattenとflatten!では、!のついた方が破壊的メソッドです。a.flattenの戻り値はフラットにした新しい配列ですが、a.flatten!の戻り…

|と||の違い

Rubyでは、演算子|は両方を評価しますが、||はショートカットショートサーキットになります。これはJavaも同じです(booleanの論理演算子|と||)。 class Rubyco def self.test if true | check print "1\n" end if true || check print "2\n" end end def sel…

scan

p "abcdababcd".scan(/b.*d/) p "abcdababcd".scan(/b.*?d/)["bcdababcd"] ["bcd", "babcd"]

0も真

Rubyでは、0は真になります。 if 0 p "Yes" else p "No" end # => Yes

ifも値を持つ

Rubyでは、ifも値を持ちます。制御構造は文ではなく式ということでしょうか。 x = 10 s = if x > 0 "Positive" elsif x < 0 then "Negative" else "Zero" end print s # => Positive

ハッシュ

Rubyでは、hash[キー]でハッシュを参照するようです。 hash = { "width" => 640, "height" => 480 } print hash["width"], "\n" # => 640 print hash["height"], "\n" # => 480

配列

Rubyでは、min...maxはmin以上max未満。 a = [ 1, 2 + 3, 4 ] for k in 0...a.length print a[k], "\n" end

ヒアドキュメント

Rubyでも、ヒアドキュメントは使えます。 name = "rubyco" print <<"EOD"; Hello, hello. Hello, my name is #{name}. EOD実行結果です。 Hello, hello. Hello, my name is rubyco.

文字列リテラル

Rubyでは、'...'と%q|...|は変数の展開をしません。"..."と%Q|...|は展開します。 name = "rubyco" print 'Hello, #{name}' ".\n" # => Hello, #{name}. (展開しない) print "Hello, #{name}.\n" # => Hello, rubyco. (展開する) print %q|#{name} says, "He…

擬似変数

Rubyでは、self, nil, true, false, __FILE__, __LINE__という擬似変数があります。トップレベルでのselfはmainです。 print self, "\n" # => main print nil, "\n" # => nil print true, "\n" # => true print false, "\n" # => false print __FILE__, "\n"…

配列に追加

開始したスレッドを配列に追加し、全員の終了をjoinで待つというプログラムの練習です。 threads = [] 10.times { |n| threads << Thread.start { 1000.times { print "#{n}," } } } threads.each { |t| t.join }

制御構造

id:nunaさんから「||は制御構造」とのコメントをいただきました。ありがとうございます。 代入(=), 三項演算子(?:), 範囲(.., ...), 否定(!, not), 短絡(&&, and ||, or), スコープ?(::)は再定義できない演算子(制御構造)のようです。 参考:演算子式