Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Adding a =~ method to the Method class

Reply
Thread Tools

Adding a =~ method to the Method class

 
 
Gabriel Saravia
Guest
Posts: n/a
 
      05-07-2009

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/.

 
Reply With Quote
 
 
 
 
KDr2
Guest
Posts: n/a
 
      05-07-2009
[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 <(E-Mail Removed)>wrote:

> CLASS_OF(method)





--
Best Regards,
-- KDr2, at x-macro.com.

 
Reply With Quote
 
 
 
 
Robert Dober
Guest
Posts: n/a
 
      05-07-2009
On Thu, May 7, 2009 at 9:02 AM, Gabriel Saravia <(E-Mail Removed)> 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

 
Reply With Quote
 
Gabriel Saravia
Guest
Posts: n/a
 
      05-07-2009
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/.

 
Reply With Quote
 
Gabriel Saravia
Guest
Posts: n/a
 
      05-07-2009
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/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Adding method from one class to another class or to instance ofanother class marekw2143 Python 3 07-25-2009 08:33 PM
instance method adding another instance method to the class Raj Singh Ruby 2 05-29-2008 10:09 PM
why a class can't access protected method from another class in thesame package,the method is interited from the ohtner class from differntpackage? junzhang1983@gmail.com Java 3 01-28-2008 02:09 AM
how to call method of the class which contains a pointer to other class method? Pawel_Iks C++ 3 07-31-2007 06:30 AM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM



Advertisments