C
Clifford Heath
I'm intrigued by the way Camping uses a method invocation to
serve as a superclass, and while exploring, possibly found a
bug? At any rate, some behaviour I can't explain... but first
a simple example of what Camping does:
class Foo
def initialize(*args)
puts "Initializing Foo"
end
end
=> nil
def Foo(*args)
puts args.inspect
Class.new(Foo) # Interesting that this works...
end
=> nil
class Bar < Foo("Hi there!")
end
["Hi there!"]
=> nil
Bar.new
Initializing Foo
=> #<Bar:0x2f84358>
Ok, all's well, and it's basically what Camping does.
Now what if I want to pass a *block* to the method
that will return my superclass?
def Foo(*args, &block)
puts args.inspect
block.call if block
Class.new(Foo)
end
=> nil
class Bar < Foo("Hi There!") {
puts "Surprise!"
}
end
["Hi there!"]
Surprise!
=> nil
Cool, that worked well. Now I want to keep the args and block passed
that was passed to the method, so I tried the following, which makes
an anonymous subclass of Foo, and Bar is a subclass of that:
class Foo
def initialize(*args)
puts "Initializing Foo"
end
end
=> nil
def Foo(*args, &block)
puts args.inspect
block.call if block
Class.new(Foo).instance_eval <<-END
def initialize
# I'm going to do something with block and args here
puts "Double surprise!"
end
self
END
end
=> nil
class Bar < Foo("Hi there!") {
puts "Surprise!"
}
end
["Hi there!"]
Surprise!
=> nil
Bar.new
Initializing Foo
=> #<Bar:0x2f776b0>
What happened to my Double surprise? It seems that instance_eval hasn't
caused Bar.new to use my extra layer of initialize... The instance of
Bar has the anonymous superclass in it's hierarchy, but the initialize()
doesn't appear in the call stack. What gives here?
Clifford Heath.
serve as a superclass, and while exploring, possibly found a
bug? At any rate, some behaviour I can't explain... but first
a simple example of what Camping does:
class Foo
def initialize(*args)
puts "Initializing Foo"
end
end
=> nil
def Foo(*args)
puts args.inspect
Class.new(Foo) # Interesting that this works...
end
=> nil
class Bar < Foo("Hi there!")
end
["Hi there!"]
=> nil
Bar.new
Initializing Foo
=> #<Bar:0x2f84358>
Ok, all's well, and it's basically what Camping does.
Now what if I want to pass a *block* to the method
that will return my superclass?
def Foo(*args, &block)
puts args.inspect
block.call if block
Class.new(Foo)
end
=> nil
class Bar < Foo("Hi There!") {
puts "Surprise!"
}
end
["Hi there!"]
Surprise!
=> nil
Cool, that worked well. Now I want to keep the args and block passed
that was passed to the method, so I tried the following, which makes
an anonymous subclass of Foo, and Bar is a subclass of that:
class Foo
def initialize(*args)
puts "Initializing Foo"
end
end
=> nil
def Foo(*args, &block)
puts args.inspect
block.call if block
Class.new(Foo).instance_eval <<-END
def initialize
# I'm going to do something with block and args here
puts "Double surprise!"
end
self
END
end
=> nil
class Bar < Foo("Hi there!") {
puts "Surprise!"
}
end
["Hi there!"]
Surprise!
=> nil
Bar.new
Initializing Foo
=> #<Bar:0x2f776b0>
What happened to my Double surprise? It seems that instance_eval hasn't
caused Bar.new to use my extra layer of initialize... The instance of
Bar has the anonymous superclass in it's hierarchy, but the initialize()
doesn't appear in the call stack. What gives here?
Clifford Heath.