injecting an instance method into another class' class method

C

Chuck Remes

I'd like to reopen a class Foo and redefine one of its methods to use an instance method from class Bar. I can't seem to figure out how to do it or even if it is possible.

I tried lots of different techniques and none have worked, so here I am asking for a bit of help. An example of one of the techniques I tried is included below.

class Foo
def self.now
Time.now.to_i
end
end

class Bar
def initialize
@bar = proc { now }

Bar.class_eval <<-code
class Foo
def Foo.now
@bar.call
end
end
code
end

def now
puts "bar now called"
end
end


I would like Foo.now to return Time.now.to_i for the normal case. However, after an instance of Bar is created, I would like the Bar instance to redefine Foo.now to call the #now instance method of Bar.

This is what the output should look like:

ruby-1.9.1-p378 > Foo.now
=> 1281540640
ruby-1.9.1-p378 > Bar.new
bar now
=> #<Bar:0x00000101216268 @bar=#<Proc:0x000001012161c0@(irb):41>>
ruby-1.9.1-p378 > Foo.now
=> "bar now called"


Is it possible to do this?

cr
 
J

Jesús Gabriel y Galán

I'd like to reopen a class Foo and redefine one of its methods to use an =
instance method from class Bar. I can't seem to figure out how to do it or =
even if it is possible.
I tried lots of different techniques and none have worked, so here I am a=
sking for a bit of help. An example of one of the techniques I tried is inc=
luded below.
class Foo
=A0def self.now
=A0 =A0Time.now.to_i
=A0end
end

class Bar
=A0def initialize
=A0 =A0@bar =3D proc { now }

=A0 =A0Bar.class_eval <<-code
=A0 =A0class Foo
=A0 =A0 =A0def Foo.now
=A0 =A0 =A0 [email protected]
=A0 =A0 =A0end
=A0 =A0end
=A0 =A0code
=A0end

=A0def now
=A0 =A0puts "bar now called"
=A0end
end


I would like Foo.now to return Time.now.to_i for the normal case. However=
, after an instance of Bar is created, I would like the Bar instance to red=
efine Foo.now to call the #now instance method of Bar.
This is what the output should look like:

ruby-1.9.1-p378 > Foo.now
=A0=3D> 1281540640
ruby-1.9.1-p378 > Bar.new
bar now
=A0=3D> #<Bar:0x00000101216268 @bar=3D#<Proc:0x000001012161c0@(irb):41>>
ruby-1.9.1-p378 > Foo.now
=A0=3D> "bar now called"


Is it possible to do this?

cr

I've managed to do it with a local variable, instead of an instance variabl=
e:

class Foo
def self.now
"Foo's now"
end
end

class Bar
def initialize
bar =3D proc {now}
class << Foo; self; end.class_eval do
define_method:)now) do
bar.call
end
end
end

def now
"Bar's now"
end
end

puts Foo.now
puts Bar.new.now
puts Foo.now

$ ruby redefine.rb
Foo's now
Bar's now
Bar's now

The problem with an instance variable is that you need to have self as
Bar's instance in order for it to work. So if you can use a local
variable and use closures, it will work, as shown above.

Jesus.
 
C

Chuck Remes

an instance method from class Bar. I can't seem to figure out how to do =
it or even if it is possible.am asking for a bit of help. An example of one of the techniques I tried =
is included below.
[snip]
I would like Foo.now to return Time.now.to_i for the normal case. =
However, after an instance of Bar is created, I would like the Bar =
instance to redefine Foo.now to call the #now instance method of Bar.
=20
I've managed to do it with a local variable, instead of an instance = variable:
=20
class Foo
def self.now
"Foo's now"
end
end
=20
class Bar
def initialize
bar =3D proc {now}
class << Foo; self; end.class_eval do
define_method:)now) do
bar.call
end
end
end
=20
def now
"Bar's now"
end
end
=20
puts Foo.now
puts Bar.new.now
puts Foo.now
=20
$ ruby redefine.rb
Foo's now
Bar's now
Bar's now
=20
The problem with an instance variable is that you need to have self as
Bar's instance in order for it to work. So if you can use a local
variable and use closures, it will work, as shown above.

Ah, excellent! I was trying to figure out how to use a closure for this =
purpose, but my mind got all turned inside out.

I'm somewhat familiar with getting the singleton class of a class using =
the "class << self;self;end" syntax, but I'm not sure what is happening =
here:

class << Foo
self # what is self here? Foo? Bar? instance of Bar?
end

My inline questions lay it out.

I'd really like to understand how that part of it is working. I =
understand the mechanics of the remaining code.

cr
 
H

hemant

Hi,

I'm somewhat familiar with getting the singleton class of a class using th=
e "class said:
class << Foo
=A0self # what is self here? Foo? Bar? instance of Bar?
end

since classes are objects too , for "class << Foo; self; end" self is
singleton (or eigenclass) class of the class object. Typically class
methods of a class are defined in its singleton class.

http://yugui.jp/articles/846


--=20
Let them talk of their oriental summer climes of everlasting
conservatories; give me the privilege of making my own summer with my
own coals.

http://gnufied.org
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top