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"]



No comments:

Post a Comment

© Railsmine