OPEN = File.method ‘open’
class File
def self.open(*a) 42 end
end
end
now restore File.open using OPEN - remember that open takes a
block…
-a
OPEN = File.method ‘open’
class File
def self.open(*a) 42 end
end
end
block…
-a
On Fri, 14 Jul 2006 [email protected] wrote:
OPEN = File.method ‘open’
class File
def self.open(*a) 42 end
end
endnow restore File.open using OPEN - remember that open takes a block…
correction. start here
open_m = File.method ‘open’
class File
def self.open(*a) 42 end
end
end
using a const makes it too easy and will accomplish what i need to do.
-a
[email protected] schrieb:
correction. start here
open_m = File.method ‘open’
class File
def self.open(*a) 42 end
end
endusing a const makes it too easy and will accomplish what i need to do.
class << File; self; end.class_eval do
remove_method :open
end
Regards,
Pit
On Fri, 14 Jul 2006, Pit C. wrote:
now restore File.open using OPEN - remember that open takes a block…
using a const makes it too easy and will accomplish what i need to do.
class << File; self; end.class_eval do
remove_method :open
end
wow. learn something every day!
~ > cat a.rb
class File
def File.open(*a) 42 end
end
p File.open(FILE)
class << File; self; end.class_eval do
remove_method :open
end
p File.open(FILE)
~ > ruby a.rb
42
#<File:a.rb>
i wasn’t aware remove_method had this ‘stacklike’ quality.
regards.
-a
On 7/14/06, [email protected] [email protected] wrote:
end
def self.open(*a) 42 end
wow. learn something every day!
end
i wasn’t aware remove_method had this ‘stacklike’ quality.
It does not, open is defined in IO, and becomes visible again
regards.
-a
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama
–
Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.
[email protected] schrieb:
remove_method :open
i wasn’t aware remove_method had this ‘stacklike’ quality.
Ara, I just called
p open_m
and noticed that “open” wasn’t a method of class “File”, but of class
“IO”! So to get back to the normal behaviour it was enough to remove the
new method of class “File”.
This is even shorter:
class << File
remove_method :open
end
The “class_eval” part isn’t necessary.
Regards,
Pit
[email protected] wrote:
remove_method :open
i wasn’t aware remove_method had this ‘stacklike’ quality.
The open method is in fact defined in IO class which is extended by File
class. In your case another method for File eigenclass class was defined
lopex
[email protected] wrote:
(class << File; self; end).instance_eval {
define_method(:open,&open_m)
}
?
T.
On Fri, 14 Jul 2006 [email protected] wrote:
(class << File; self; end).instance_eval {
define_method(:open,&open_m)
and the block?
-a
On 7/14/06, [email protected] [email protected] wrote:
- h.h. the 14th dali lama
I had to cheat
File::OPEN_M = open_m
class File
eval "
def self.open(*args, &block)
OPEN_M.call(*args, &block)
end
"
end
The problem is - as I’m sure you know - that define_method doesn’t
honour the block argument of the method reference. I’d be very
interested to see if you can do it cleanly in ruby 1.8.
Regards,
Sean
On Fri, 14 Jul 2006, Robert D. wrote:
It does not, open is defined in IO, and becomes visible again
duh - need more coffee. so - back to original challenge!
-a
On 7/14/06, Sean O’Halpin [email protected] wrote:
suffering increases your inner strength. also, the wishing for
OPEN_M.call(*args, &block)
Block behavior is preserved though when we store a reference to a method
e.g.
----------------------- 8< ------------------------------
class X
def x(*args,&block)
block.call(1764) if block
end
end
OLD = X.instance_method :x
class X
def x; “rubbish”; end
end
class X
define_method(:x, OLD )
end
X.new.x{ |a| puts a }
----------------------- >8 ----------------------------------
That should do the trick, no?
But I cannot make it work with IO :(, some internal magic, maybe?
Cheers
Robert
On 7/14/06, Robert D. [email protected] wrote:
–
def self.open(*args, &block)
Seanend
Excellent. Don’t use the & to convert the Proc into a block - just use
the method reference directly.
Are you getting the “singleton method called for a different object
(TypeError)” error?
Thanks,
Sean
[snip]
Excellent. Don’t use the & to convert the Proc into a block - just use
the method reference directly.
Too much honor, I seem to post too fast, furthermore the idea is ara’s
not
mine
Are you getting the "singleton method called for a different object
(TypeError)" error?
Thanks,
Sean
Exactly
and though my original code is not well documenting the behavior ara is
exploiting it really does seem to be a problem because of the “internal”
nature of IO.
Here is eventually the code mimicking the structure of the inherited
class
method “open” and one can see that it works perfectly well:
class X # role of IO
class << self
def x(*args,&block) # role of open
block.call(1764) if block
end
end
end
OLD = X.method :x
class Y < X # role of File
class << self
def x; “rubbish”; end
end
end
class Y
class << self
define_method(:x, OLD )
end
end
Y.x{ |a| puts a }
Cheers
Robert
On 7/14/06, Robert D. [email protected] wrote:
nature of IO.
define_method(:x, OLD ) end
end
Y.x{ |a| puts a }
Cheers
Robert
Hmmm. I’m still getting “singleton method called for a different
object (TypeError)” for this (ruby 1.8.4 (2005-12-24) [i386-mswin32]).
Sean
[SOLUTION]
OPEN =File.method ‘open’
class File
def self.open(*a) 42 end
end
class File
class << self
def open(*args,&block)
OPEN.call(*args, &block)
end
end
end
x=File.open(FILE){
|f|
puts f.read
}
Please do not flame me I am aware of the shortcomings( at least I hope
so),
but I just did not get the Metaprogramming to work, it would be good to
know
why!
Cheers
Robert
On 7/14/06, Sean O’Halpin [email protected] wrote:
The problem is - as I’m sure you know - that define_method doesn’t
honour the block argument of the method reference. I’d be very
interested to see if you can do it cleanly in ruby 1.8.Regards,
Sean
Replying to myself to correct an error - it’s the implicit to_proc (&)
that strips the block argument, not define_method itself.
This illustrates the (perhaps surprising) behaviour:
def m1(*args, &block)
p args
block.call if block_given?
end
m1(1) do
puts “m1”
end
meth = method(:m1)
Object.instance_eval { define_method :m2, meth }
m2(2) do
puts “m2”
end
Object.instance_eval { define_method :m3, &meth }
m3(3) do # this block is not called
puts “m3”
end
END
[1]
m1
[2]
m2
[3]
Regards,
Sean
On 7/14/06, [email protected] [email protected] wrote:
On Fri, 14 Jul 2006, Sean O’Halpin wrote:
Hmmm. I’m still getting “singleton method called for a different
object (TypeError)” for this (ruby 1.8.4 (2005-12-24) [i386-mswin32]).[SNIP]
you robert?
Me too, what was I executing???
Sorry,
btw. this challenge was not arbitrary: the increase in metaprogramming
On 7/14/06, [email protected] [email protected] wrote:
def x(*args,&block) # role of open end
you robert?
instance_method 42
class_method{but, of course, we are seeing that it doesn’t work.
regards.
-a
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama
In most cases, this works:
class Foo
def self.open(*args, &block)
p [args, block]
yield if block_given?
end
end
Foo.open(1) do
puts “hello”
end
open_m = Foo.method ‘open’
class Foo
def self.open(*a) p 42 end
end
Foo.open(2) do
puts “hello”
end
(class << Foo; self; end).instance_eval do
define_method(:open, open_m)
end
Foo.open(3) do
puts “bye”
end
END
[[1],
#Proc:0x02869018@c:/rubylib/experiments/redefine-class-method.rb:8]
hello
42
[[3],
#Proc:0x02867728@c:/rubylib/experiments/redefine-class-method.rb:26]
bye
but as we’ve seen, it doesn’t work in the case of the File(IO)
singleton. To be honest, I’m not clear about exactly what kind of
object the File(IO) singleton is. Anyone offer any enlightenment?
Regards,
Sean
On Sat, Jul 15, 2006 at 10:33:09AM +0900, Sean O’Halpin wrote:
On 7/14/06, [email protected] [email protected] wrote:
On Fri, 14 Jul 2006, Sean O’Halpin wrote:
In most cases, this works:class Foo
def self.open(*args, &block)
p [args, block]
yield if block_given?
end
end
[…]
(class << Foo; self; end).instance_eval do
define_method(:open, open_m)
end
[…]
but as we’ve seen, it doesn’t work in the case of the File(IO)
singleton. To be honest, I’m not clear about exactly what kind of
object the File(IO) singleton is. Anyone offer any enlightenment?
Open is a singleton method of IO, not File; this is why the call fails
(in
1.9, it’d happen earlier, as soon as you try to rebind the method).
There’s
nothing that special about File itself:
class X
def self.foo; yield + 1 end
end
class Y < X
end
Y.foo{1} # => 2
m = Y.method(:foo)
def Y.foo; 10 end
Y.foo{1} # => 10
class << Y; self end.class_eval{define_method(:foo, m)}
Y.foo{1} # =>
(TypeError)
As for the File(IO) notation, it seems to mean that the singleton method
belongs to IO:
class X; def self.foo; yield + 1 end end
class Y < X; end
Y.method(:foo) # => #<Method: Y(X).foo>
X.method(:foo) # => #<Method: X.foo>
Keep in mind that the singleton class of a class is derived from that of
its
superclass:
class X; def self.foo; 1 end end
class Y < X; end
X.methods(false) # => [“foo”]
Y.methods(false) # => []
Y.foo # => 1
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