文字列リテラル

Rubyでは、'...'と%q|...|は変数の展開をしません。"..."と%Q|...|は展開します。

name = "rubyco"
print 'Hello, #{name}' ".\n"            # => Hello, #{name}.        (展開しない)
print "Hello, #{name}.\n"               # => Hello, rubyco.         (展開する)
print %q|#{name} says, "Hello."| "\n"   # => #{name} says, "Hello." (展開しない)
print %Q|#{name} says, "Hello."|  "\n"  # => rubyco says, "Hello."  (展開する)

実行結果です。

Hello, #{name}.
Hello, rubyco.
#{name} says, "Hello."
rubyco says, "Hello."

|と||の違い

Rubyでは、演算子|は両方を評価しますが、||はショートカットショートサーキットになります。これはJavaも同じです(booleanの論理演算子|と||)。

class Rubyco
    def self.test
        if true | check
            print "1\n"
        end
        if true || check
            print "2\n"
        end
    end

    def self.check
        print "Check\n"
        true
    end
end

Rubyco.test

実行結果。

Check
1
2

疑問:どうしてri "TrueClass#|"は調べられるのに ri "TrueClass#||"は調べられないのでしょうね。それは||のほうはLispで言うところの特殊形式だからでしょうか。メソッドの引数のように評価しないからでしょうか。riで||を調べるにはどうしたら良いのでしょう。→制御構造

>ri "TrueClass#|"
------------------------------------------------------------ TrueClass#|
     true | obj   => true
------------------------------------------------------------------------
     Or---Returns +true+. As _anObject_ is an argument to a method call,
     it is always evaluated; there is no short-circuit evaluation in
     this case.

        true |  puts("or")
        true || puts("logical or")

     _produces:_

        or



>ri "TrueClass#||"
Nothing known about TrueClass#||

追記:
コメントでs/ショートカット/ショートサーキット/を教えていただきました。感謝!

flattenとflatten!

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

a = ["A", ["B", "C"], ["D", "E"]]
p a

b = a.flatten
p b

if a == b
    print "flatten: same\n"
else
    print "flatten: not same\n"
end

b = a.flatten!
p a

if a == b
    print "flatten!: same\n"
else
    print "flatten!: not same\n"
end

実行結果です。

["A", ["B", "C"], ["D", "E"]]
["A", "B", "C", "D", "E"]
flatten: not same
["A", "B", "C", "D", "E"]
flatten!: same

attr_readerでアクセサ作り

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

class Rubyco
    attr_reader :attr1

    def initialize(attr1, attr2)
        @attr1 = attr1
        @attr2 = attr2
    end
end

o = Rubyco.new(123, 456)
p o.attr1
p o.attr2

実行結果の抜粋です。

123
undefined method `attr2' for #<Rubyco:0x2946f58 @attr2=456, @attr1=123> (NoMethodError)

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 run>
#<Thread:0x29470c0 run>
#<Thread:0x29470c0 run>
#<Thread:0x29470c0 run>
#<Thread:0x29470c0 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>
#<Thread:0x2946f40 run>

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 "Hello".twice.debug_print

実行結果。

Debug: Hello
"Hello"
Debug: HelloHello
"HelloHello"