![]() |
Adding a =~ method to the Method class
The Ruby API specifies that objects of the Method class have an instance method "==": "Two method objects are equal if that are bound to the same object and contain the same body." At this moment, I would very much like it if it also had a "=~" method: "two method objects are similar if they contain the same body but are NOT necessarily bound to the same object" unfortunately I'm not currently skilled enough to really understand the C code in which the "==" method for the Method class is written. could someone help me out here? Below I've replicated the C code for the "==" method with some changes to reflect what the =~ method would look like: static VALUE method_similar(method, other) VALUE method, other; { struct METHOD *m1, *m2; if (TYPE(other) != T_DATA || RDATA(other)->dmark != (RUBY_DATA_FUNC)bm_mark) return Qfalse; //I Do Not understand what this if statement does if (CLASS_OF(method) != CLASS_OF(other)) return Qfalse; //I assume this makes sure that the classes of both methods is Method? Data_Get_Struct(method, struct METHOD, m1);//No clue but looks harmless enough Data_Get_Struct(other, struct METHOD, m2); //No clue but looks harmless enough if (m1->klass != m2->klass || m1->rklass != m2->rklass || //this condition looks like it ALSO checks that the classes of both methods is Method, so I must be missing something somewhere... m1->recv != m2->recv || // <-!! Would all that need to happen is this line be eliminated?? m1->body != m2->body) return Qfalse; return Qtrue; } Also, how can you modify Ruby to include this function, so i can use it in my Rails tests? -Gabe -- Posted via http://www.ruby-forum.com/. |
Re: Adding a =~ method to the Method class
[Note: parts of this message were removed to make it a legal post.]
*ruby-1.8.7-p160* add to *eval.c,* after line *9323*: static VALUE method_similar(method, other) VALUE method, other; { struct METHOD *m1, *m2; if (TYPE(other) != T_DATA || RDATA(other)->dmark != (RUBY_DATA_FUNC)bm_mark) return Qfalse; if (CLASS_OF(method) != CLASS_OF(other)) return Qfalse; Data_Get_Struct(method, struct METHOD, m1); Data_Get_Struct(other, struct METHOD, m2); if (m1->klass != m2->klass || m1->rklass != m2->rklass ||m1->body != m2->body) return Qfalse; return Qtrue; } add to *eval.c* affter line *10046*: rb_define_method(rb_cMethod, "=~", method_similar, 1); On Thu, May 7, 2009 at 3:02 PM, Gabriel Saravia <gabe.saravia@gmail.com>wrote: > CLASS_OF(method) -- Best Regards, -- KDr2, at x-macro.com. |
Re: Adding a =~ method to the Method class
On Thu, May 7, 2009 at 9:02 AM, Gabriel Saravia <gabe.saravia@gmail.com> wr=
ote: > What about class UnboundMethod def similar? other case other when self.class self =3D=3D other when BoundMethod self =3D=3D other.unbind else false # or if you prefer raise WhateverSeemsFit, "blah" end end end class BoundMethod def similar? other case other when self.class unbind =3D=3D other.unbind etc.etc. Cheers Robert --=20 Si tu veux construire un bateau ... Ne rassemble pas des hommes pour aller chercher du bois, pr=E9parer des outils, r=E9partir les t=E2ches, all=E9ger le travail=85 mais enseigne aux gens la nostalgie de l=92infini de la mer. If you want to build a ship, don=92t herd people together to collect wood and don=92t assign them tasks and work, but rather teach them to long for the endless immensity of the sea. -- Antoine de Saint-Exup=E9ry |
Re: Adding a =~ method to the Method class
Thank you for the quick response!
To answer the other post about an example, The particular use I have for it was that I had an abstract class deriving from ActiveRecord. It made sense to override many of ActiveRecord's class methods: The AbstractClass methods are passed some params in addition to those standard to the ActiveRecord method, which it then uses those params to delegate onto the correct concrete sub class, to which it passes the standard ActiveRecord params. However, in the subclasses of this abstract class, I re-instate the ActiveRecord class methods. So, in order to test that I had actually reinstated the ActiveRecord methods, I needed to assert that my concrete sub class was using the ActiveRecord method and not the abstract one. so... !(MyAbstractClass.method(:find) == ActiveRecord::Base.method(:find)) but, MyConcreteSubclass.method(:find) =~ ActiveRecord::Base.method(:find) incidentally, since posting I attempted to go to bed, but couldn't, kept on thinking about the problem, when I remembered vaguely about unbound methods and came up with this purely ruby method solution: def test_class_methods_similar(klass1, klass2, method_name_symbol) unbound_method1 = klass1.method(method_name_symbol).unbind unbound_method2 = klass2.method(method_name_symbol).unbind unbound_method1 == unbound_method2 end The importance of the test truly came out when it helped me catch a bug - I had overwritten many methods, and had accidentally overwritten destroy with destroy_all. however, I like the posted solutions better for readability and the fact that it can be called directly from a class. and, did that post really come from matz? I ask because seeing as how I'm fairly new, (to Ruby, to Rails, etc.) and this is my first post ever to the Ruby forum, I'm feeling a slight sense of awe. just want to say, Ruby is a beautiful language. It has made me love programming after many of my college courses had pretty much destroyed any such thought. I must ask, any chance Method.=~ could make it into the Ruby codebase? I figure it must have a lot more uses whenever a solution involves overriding/passing around methods between classes, including most any use of alias_method? -Gabe KDr2 wrote: > *ruby-1.8.7-p160* > add to *eval.c,* after line *9323*: > > static VALUE > method_similar(method, other) > VALUE method, other; > { > struct METHOD *m1, *m2; > > if (TYPE(other) != T_DATA || RDATA(other)->dmark != > (RUBY_DATA_FUNC)bm_mark) > return Qfalse; > if (CLASS_OF(method) != CLASS_OF(other)) > return Qfalse; > > Data_Get_Struct(method, struct METHOD, m1); > Data_Get_Struct(other, struct METHOD, m2); > > if (m1->klass != m2->klass || m1->rklass != m2->rklass ||m1->body != > m2->body) > return Qfalse; > > return Qtrue; > } > > add to *eval.c* affter line *10046*: > > rb_define_method(rb_cMethod, "=~", method_similar, 1); -- Posted via http://www.ruby-forum.com/. |
Re: Adding a =~ method to the Method class
Robert Dober wrote:
> and thanks for this too, now I can add it without having to write C and recompile! > Cheers > Robert Cheers indeed! -Gabe -- Posted via http://www.ruby-forum.com/. |
| All times are GMT. The time now is 11:59 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.