I'm practicing ducktyping now in Ruby, and am trying to modify an argument's value based on another argument passed to the same method. However, it just doesn't work.
For example:
class Duck
attr_reader :foo, :bar
def initialize
@foo = false
@bar = false
end
def duck_foo
ducktype(@foo, @bar)
end
def duck_bar
ducktype(@bar, @foo)
end
def ducktype(duck1, duck2)
p duck1 #=> false
p duck2 #=> false
puts "foo: #{foo} bar: #{bar}" #=> "foo: false bar: false"
duck1 = true if duck2 == false #<= For #duck_foo: I want to make @foo = true if @bar == false. But it only changes duck1 to true. / For #duck_bar: I want to make @bar = true.
p duck1 #=> true
p duck2 #=> false
puts "foo: #{foo} bar: #{bar}" #=> "foo: false bar: false" => @foo is still false. I want it true!
end
end
duck = Duck.new
duck.duck_foo
duck.duck_bar
The output for #duck_foo, I expect to see is @foo becomes true. However, it only changes duck1 to true and @foo is still false.
How can I make it work?
In essence, I'm trying to make:
def duck_foo
p foo
p bar
puts "foo: #{foo} bar: #{bar}"
@foo = true if @bar == false #=> change @foo to true.
p foo
p bar
puts "foo: #{foo} bar: #{bar}"
end
def duck_bar
p foo
p bar
puts "foo: #{foo} bar: #{bar}"
@bar = true if @foo == false #=> change @bar to true.
p foo
p bar
puts "foo: #{foo} bar: #{bar}"
end
Into:
def duck_foo
ducktype(@foo, @bar)
end
def duck_bar
ducktype(@bar, @foo)
end
def ducktype(duck1, duck2)
#whatever code necessary to preserve the original methods' behavior.
end
So the code is cleaner and easier to maintain.
Hope this makes sense. Thanks everyone!