Created
November 8, 2012 21:00
-
-
Save jimweirich/4041577 to your computer and use it in GitHub Desktop.
Ruby Trivia
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Dog | |
def wag(tail=my_tail) | |
tail | |
end | |
def my_tail | |
:dogs_tail | |
end | |
end | |
class Cat | |
def wag_dog | |
Dog.new.wag | |
end | |
def my_tail | |
:cats_tail | |
end | |
end | |
puts Cat.new.wag_dog # What is printed here? | |
# Make a prediction before you try it. |
Here's another variation that might also cause confusion:
class Dog
def wag(tail=my_tail)
tail
end
def self.my_tail
:dogs_tail
end
def my_tail
:fidos_tail
end
end
puts Dog.new.wag
Since the default value looks like it is called outside of the method it could be mistaken as a class method.
I thought this was confusing at first, until I realised what self
would be in the implicit my_tail
method call. Now it's hard to see any other result!
class Dog
def make_noise(sound = (p self; :bark))
sound
end
end
class Cat
def dog_sound
Dog.new.make_noise
end
end
Cat.new.dog_sound
class A
def foo a, b=a
puts a; puts b
end
end
class B < A
def foo a
super
puts 'B'
end
end
m = A.instance_method :foo
puts "invoking on an A"
A.new.foo :bar
puts "*" * 31
puts "invoking on a B"
B.new.foo :blat
puts "*" * 31
puts "binding to a B"
m.bind(B.new).call :baz
A little twist...
class A
def foo a, b=a
puts a; puts b
end
end
class B < A
def foo a
super
puts 'B'
end
end
m = A.instance_method :foo
puts "invoking on an A"
A.new.foo :bar
puts "*" * 31
puts "invoking on a B"
b=B.new
b.foo :blat
puts "*" * 31
puts "binding to a B"
m.bind(b).call :baz
puts "*" * 31
puts "invoking on a B"
b.foo :blat
I think any confusion stems from the chained Dog.new.wag
If you instead wrote that your cat wagged its dog thusly:
dog = Dog.new
dog.wag
I hope no one would think that the wag method on dog somehow reaches back to it's caller to get a parameter it wasn't passed...
- its
now with lambdas... (ok, I suck at this)
dog = ->{ :dogs_tail }
cat = ->(dog){ dog.call }
devious_kitty = ->(cat,dog) {|cat| cat.call(dog) }
devious_kitty.call(cat,dog)
Putted even more simply it's all about this:
Foo = Class.new do
def bar(x=self)
x
end
end
Foo.new.bar
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's evaluated in the context of the method. Try this
var = yield
. :)