Navigation

Sunday, January 31, 2010

Menggunakan Instance Eval Untuk Implementasi Ruby Block

Artikel ini dibuat berdasarkan pertanyaan pada StackOverflow mengenai implementasi Ruby block. Pada saat implementasi Ruby block, lebih baik menggunakan instance_eval dibandingkan dengan yield. Berikut ini adalah contohnya.
1. Dengan menggunakan yield.
class MyClass
    def initialize
        @my_array = []
    end

    def elements
        block_given? ? yield(self) : @my_array
    end

    def add_element( text )
        @my_array << text
    end
end

# DOES NOT work
my_object = MyClass.new
my_object.elements {
    add_element "hello"
    add_element "world"
} # => NoMethodError: undefined method `add_element' for main:Object
p my_object.elements # => []

# this works
my_object = MyClass.new
my_object.elements { |a|
    a.add_element "hello"
    a.add_element "world"
}
p my_object.elements  # => ["hello", "world"]
2. Dengan menggunakan instance_eval
class MyClass
    def initialize
        @my_array = []
    end

    def elements(&block)
        block_given? ? instance_eval(&block) : @my_array
    end

    def add_element( text )
        @my_array << text
    end
end

# This works
my_object = MyClass.new
my_object.elements {
    add_element "hello"
    add_element "world"
}
p my_object.elements # => ["hello", "world"]

# works too
my_object = MyClass.new
my_object.elements { |a|
    a.add_element "hello"
    a.add_element "world"
}
p my_object.elements # => ["hello", "world"]



0 comments:

Post a Comment