given the below, if you were not allowed to modify class X
module N
def foo
end
end
module M
…
end
class X
extend M
end
would it possible for
x = X.new
to somehow call foo as an instance method of x?
given the below, if you were not allowed to modify class X
module N
def foo
end
end
module M
end
class X
extend M
end
would it possible for
x = X.new
to somehow call foo as an instance method of x?
On Thu, 4 May 2006, polypus wrote:
end
class X
extend M
endwould it possible for
x = X.new
to somehow call foo as an instance method of x?
harp:~ > cat a.rb
module N
def foo() p 42 end
end
module M
include N
end
class X
include M
end
x = X.new
x.foo
harp:~ > ruby a.rb
42
-a
class X
include M
end
thanks, but you modified class X, which was my provision that you should
not do.
– Daniel
thanks, close but no cigar. notice that i want X.new to call foo. i
don’t think that it’s possible.
the solution should read exactly as i wrote it, the only modifications
allowed are to the body of the two modules.
On May 3, 2006, at 11:59 PM, polypus wrote:
would it possible for
x = X.new
module N
def foo() “foo” end
end
class X
end
x = X.new
class << x
include N
end
x.foo # => “foo”
– Daniel
Obviously I modified more than the 2 modules. This is the best you’re
gonna do, cause I don’t think extend has anything that can act as a
“callback,” ala append_features
class Object
alias_method :old_extend,:extend
def extend(mod)
include(mod) if self == X
old_extend(mod)
end
end
module N
def foo
“N#foo”
end
end
module M
include N
end
class X
extend M
end
puts X.new.foo # N#foo
On Thu, May 04, 2006 at 06:59:59AM +0900, polypus wrote:
end
class X
extend M
endwould it possible for
x = X.new
to somehow call foo as an instance method of x?
module N
class << self; attr_accessor :bleh end # just to prove #foo was run
self.bleh = “#foo not executed”
def foo
N.bleh = “#foo was executed!!”
end
end
module M
def self.extend_object(o)
o.class_eval do
include N
def self.new(*a,&b)
r = super(*a, &b) # explicit -> less stuff to remember
r.foo # is this what you meant?? weird.
# why won’t X.new.foo do?
r
end
end
end
end
class X
extend M
end
x = X.new # => #<X:0xb7e2f034>
RUBY_VERSION # => “1.8.4”
N.bleh # => “#foo was
executed!!”
Now, care to explain the intended use of this?
Or is it just a pointless exercise?
On Thu, 4 May 2006, polypus wrote:
class X
include M
endthanks, but you modified class X, which was my provision that you should
not do.
sorry. i assumed since you said
class X
extend M
end
that you didn’t really mean it
-a
I had no idea that extend has an append_features-style callback, you
learn something every day. Thanks Mauricio.
On Thu, 4 May 2006, Mike H. wrote:
I had no idea that extend has an append_features-style callback, you
learn something every day. Thanks Mauricio.
i think you should elaborate on what you really want, what mauricio
posted,
though cool, definitely modifies the class:
harp:~ > cat a.rb
module N
class << self; attr_accessor :bleh end # just to prove #foo was run
self.bleh = “#foo not executed”
def foo
N.bleh = “#foo was executed!!”
end
end
module M
def self.extend_object(o)
o.class_eval do
include N
def self.new(*a,&b)
r = super(*a, &b) # explicit -> less stuff to remember
r.foo # is this what you meant?? weird.
# why won’t X.new.foo do?
r
end
end
end
end
class X
p ancestors
extend M
p ancestors
end
harp:~ > ruby a.rb
[X, Object, Kernel]
[X, N, Object, Kernel]
what, exactly do you mean when you say the class must not be modified?
both
the solution i posted and this one modify the class in exactly the same
way :
by including a module in the class.
what you originally posted:
class X
extend M
endwould it possible for
x = X.new
to somehow call foo as an instance method of x?
iff you really do not modify the class X, can be accomplished thus:
harp:~ > cat a.rb
module N
def foo() p 42 end
end
module M
include N
end
class X; end
x = X.new
x.extend M
x.foo
harp:~ > ruby a.rb
42
any other way to be able to call x.foo will, in fact, modify the class
X. but
maybe that’s not what you really want?
regards.
-a
ok for those who like pointless exercises here is a harder version.
rules:
module N
def foo
puts self
end
end
module M
…
end
class X
extend M
end
X.new
yes there is a solution, good luck
On May 4, 2006, at 10:14 PM, polypus wrote:
print something like #<X:0xb7e188a4>
…–
Posted via http://www.ruby-forum.com/.
module M
class ::X
include N
end
end
ok i guess i need a rule 5, you may not mention class X in your code
module M
class ::X
include N
end
end
also you did not solve rule 3
thanks a lot everybody, you have helped me simplify my library
interface.
mauricio you solved it. i knew about the extend callback and am already
in fact using it in the project from whence the very point-full exercise
was distilled, but i hadn’t thought of your solution, so thanks. unknown
(ara?) you’re right my definition of ‘not modify’ was not clear, i just
meant do not modify my code listing, while modifying class in memory was
fine. i’ll be releasing my project as a gem and will announce it on list
when i do so mauricio you’ll see your answer in action.
to illustrate my point, now the user of my lib can go
class X
extend M
end
instead of
class X
extend M
def initialize
init_lib
end
end
it’s not really a huge deal, but hey it’s one less thing for the user to
need to know/worry about. and i’ve always wondered if it was possible.
On May 4, 2006, at 10:31 PM, polypus wrote:
also you did not solve rule 3
–
Posted via http://www.ruby-forum.com/.
eh It was a joke answer anyway :-p
hallelujah!
wasn’t that hard for you was it?
wondering whether it wouldn’t be a good one for rubyquiz though.
On Fri, 5 May 2006, polypus wrote:
- you may not use class_eval, module_eval, or use the extend_object
endclass X
extend M
endX.new
yes there is a solution, good luck
harp:~ > cat a.rb
module N
def foo() puts self end
end
module M
def new(*a, &b)
obj = super
obj.extend N
obj.foo
obj
end
end
class X
extend M
end
X.new
harp:~ > ruby a.rb
#<X:0xb75d196c>
-a
On May 4, 2006, at 10:31 PM, polypus wrote:
also you did not solve rule 3
–
Posted via http://www.ruby-forum.com/.
Here’s some more whacky code:
% cat whackextend.rb
module M
$old_extend = Object.instance_method(:extend)
class ::Object
def extend(other)
if other.name == “M”
eval %Q{
class #{self}
include N
def initialize
foo
end
end
}
else
$old_extend.bind(self).call(other)
end
end
end
end
I’m pretty sure it follows all your rules.
test
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs