This challenge is quite uncommon since it isn’t ‘algorithmic’ nor ‘obfuscating’.
You might want to play with this if you enjoy messing around with
singletons.
[NOTE: read the end of the message!]
···
Your mission, should you choose to accept it, is to fill in the code
below so that its execution terminates without error and the output
is
You won!
module NoOverloading
def no_redef(*args)
@no_override ||=
args.each { |i| @no_override << i }
end
def no_redef_list
supmethods =
(ancestors - [self]).each do |i|
begin
supmethods += ( i.no_redef_list || )
rescue NameError
end
end
(@no_override || ) + supmethods
end
def inherited sub
class << sub
def method_added(id)
return if no_redef_list.index(id) == nil
remove_method id
end
def alias_method a, b
# catcha!
end
self.freeze
end
end
self.freeze
end
module Unbreakable
class A
extend NoOverloading
no_redef :a
def a; puts “You lost!”; end
end
class Caller
def self.foo(arg)
raise “Only classes derived from A!” unless arg.kind_of?
Unbreakable::A
arg.a
end
end
Caller.freeze
A.freeze
self.freeze
end
class B < Unbreakable::A
def a; puts “You won!”; end
PUT YOUR CODE HERE!
end
Unbreakable::Caller.foo( B.new )
Details
You are expected to subclass Unbreakable::A and find a way to override
method #a. Normally all your code should be in the indicated position.
Class B must be directly derived from Unbreakable::A. The following is
not a valid solution:
class B
def a; puts “You won!”; end
def kind_of? a
true
end
end
Warning
This mission is, to the best of my current knowledge, impossible.
_________________________________________________________________
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
…Deep Hack Mode – that mysterious and frightening state of
consciousness where Mortal Users fear to tread.
– Matt Welsh
Hi,
You are expected to subclass Unbreakable::A and find a way to override
method #a. Normally all your code should be in the indicated position.
Class B must be directly derived from Unbreakable::A. The following is
not a valid solution:
class B
def a; puts “You won!”; end
def kind_of? a
true
end
end
Warning
This mission is, to the best of my current knowledge, impossible.
Is this a valid answer?
class B < Unbreakable::A
def a; puts “You won!”; end
# PUT YOUR CODE HERE!
p Unbreakable::A.instance_eval{@no_override.clear}
def a; puts “You won!”; end
end
matz.
···
In message “[contest] Code challenge” on 03/02/05, Mauricio Fernández batsman.geo@yahoo.com writes:
I guess yes.
To be honest I thought of that but either overlooked its potential or
forgot to freeze the class iv. (can’t remember)
Wish I could say I
left it as a back-door, but that is not the case.
But now, what happens if I do:
…
def no_redef(*args)
@no_override ||=
args.each { |i| @no_override << i }
@no_override.freeze
end
…
Is it impossible enough now? 
My ultimate goal with this contest is seeing if it is at all possible to
prevent redefinition unconditionally, against all attacks.
And I learn a great deal along the way, too.
···
On Wed, Feb 05, 2003 at 05:01:28AM +0900, Yukihiro Matsumoto wrote:
Hi,
In message “[contest] Code challenge” > on 03/02/05, Mauricio Fernández batsman.geo@yahoo.com writes:
You are expected to subclass Unbreakable::A and find a way to override
method #a. Normally all your code should be in the indicated position.
Class B must be directly derived from Unbreakable::A. The following is
not a valid solution:
class B
def a; puts “You won!”; end
def kind_of? a
true
end
end
Warning
This mission is, to the best of my current knowledge, impossible.
Is this a valid answer?
class B < Unbreakable::A
def a; puts “You won!”; end
# PUT YOUR CODE HERE!
p Unbreakable::A.instance_eval{@no_override.clear}
def a; puts “You won!”; end
end
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Never make any mistaeks.
– Anonymous, in a mail discussion about to a kernel bug report
But now, what happens if I do:
…
def no_redef(*args)
@no_override ||=
args.each { |i| @no_override << i }
@no_override.freeze
end
…
Is it impossible enough now? 
Not quite. Here are my 5 solutions:
Solution 1: Redefine Array#+
class B < Unbreakable::A
def a; puts “You won!”; end
Array.class_eval do
def +(x)
return
end
end
def a; puts “You won!”; end
end
Solution 2: Redefine Array#index
class B < Unbreakable::A
def a; puts “You won!”; end
Array.class_eval do
def index(id)
return nil
end
end
def a; puts “You won!”; end
end
Solution 3: Redefine Fixnum#==
class B < Unbreakable::A
def a; puts “You won!”; end
Fixnum.instance_eval do
define_method(:==) { |x| true }
end
def a; puts “You won!”; end
end
Solution 4: Use alias_method to create an alias for alias_method so
that I can still create aliases in the derived class.
class B < Unbreakable::A
def a; puts “You won!”; end
Module.instance_eval do
alias_method :alias_method_2, :alias_method
end
def b; puts “You won!”; end
alias_method_2 :a, :b
end
Solution 5: Use set_trace_func to capture all bindings; use this so
that any method that any calls no_redef_list are equivalent to
“return”.
class B < Unbreakable::A
def a; puts “You won!”; end
call_stack =
current_call = nil
set_trace_func(proc {|*args|
if args[3] == :no_redef_list then
eval “return”, call_stack[4]
end
case args[0]
when ‘call’
call_stack.unshift(current_call)
when ‘return’
call_stack.shift()
end
current_call = args
})
def a; puts “You won!”; end
set_trace_func nil
end
My ultimate goal with this contest is seeing if it is at all possible to
prevent redefinition unconditionally, against all attacks.
My suspicion is that this is not possible without modifying the
interpreter. I also suspect that protecting against all “attacks” is
unnecessary, and that protecting the programmer against shooting himself
in the foot is sufficient.
Paul
···
On Wed, Feb 05, 2003 at 06:00:43AM +0900, Mauricio Fernández wrote:
But now, what happens if I do:
…
def no_redef(*args)
@no_override ||=
args.each { |i| @no_override << i }
@no_override.freeze
end
…
Is it impossible enough now? 
Not quite. Here are my 5 solutions:
Ouch!
Solution 1: Redefine Array#+
…
Solution 2: Redefine Array#index
…
Solution 3: Redefine Fixnum#==
…
Solution 4: Use alias_method to create an alias for alias_method so
that I can still create aliases in the derived class.
I guess I’d have to freeze everything I use inside NoOverloading to
prevent these and modify alias_method on Module…
Another possibility is implementing my own cheap Array class.
Solution 5: Use set_trace_func to capture all bindings; use this so
that any method that any calls no_redef_list are equivalent to
“return”.
And remove Kernel.set_trace_func.
My ultimate goal with this contest is seeing if it is at all possible to
prevent redefinition unconditionally, against all attacks.
My suspicion is that this is not possible without modifying the
interpreter. I also suspect that protecting against all “attacks” is
unnecessary, and that protecting the programmer against shooting himself
in the foot is sufficient.
Was rather thinking of another way to do Rubyrobots without using safe
levels, that’s all.
At least I learned something in the process, and first thing: forget
about doing code contests for some time until I know quite a lot more 
I’ll keep “closing holes” on the Wiki in case anybody is interested on
seeing if this will ever work.
···
On Wed, Feb 05, 2003 at 07:31:49AM +0900, Paul Brannan wrote:
On Wed, Feb 05, 2003 at 06:00:43AM +0900, Mauricio Fernández wrote:
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Alan Cox wrote:
[…]
No I didnt. Someone else wrote that. Please keep attributions
straight.
– From linux-kernel