# Methods depend on pairs of objects - best parctise pls?

**URL:** <https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630>\
**Category:** Ruby\
**Created:** [July 24, 2009, 9:18am UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630 "2009-07-24T09:18:23Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![orenshani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/e47c2d/32.png) [@orenshani](https://www.ruby-forum.com/u/orenshani)\
**Post date:** [July 24, 2009, 9:18am UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630/1 "2009-07-24T09:18:23Z")

</div>

Hi All,

First of all I think you should know that I am quite new to Ruby. I have  
many years of experience with other programming languages tough, and I  
must say that Ruby is really great!

And now to my question - I am working on something that makes use of  
proximity functions, which are functions that take two objects (“base”  
and “reference”) and return a real number in the range of [0…1], based  
on how “the same” the objects are (1 means identical, 0 means completley  
different and a fractions means a certain degree of proximity). The  
objects do not have to be of the same type. For example, a number can be  
compared to a range, a string can be compared to a regular expression,  
etc, but of course, not all combinations are possible.

Now the point is that the process for calculating the proximity very  
much depends on the types of objects compared, so it is actually a  
method of the objects-pair, so the most obvious thing I can do is define  
a class for each valid pair combination, but that does not seem to me as  
very elegant. Another thing I can do is to define the proximity function  
as a method of each object and somehow re-define the needed sub-methods  
per each class of valid reference-object, but that still looks a little  
messy, I think.

So does anyone have any other ideas for doing this kind of object-pairs  
dependent coding, is ther some kind of best-practice for this situation?

Your thoughts and ideas are much appreciated!

Oren

---

<div class="post-metadata">

**Author:** ![orenshani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/e47c2d/32.png) [@orenshani](https://www.ruby-forum.com/u/orenshani)\
**Post date:** [July 24, 2009, 11:42am UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630/2 "2009-07-24T11:42:25Z")

</div>

Max W. wrote:

> ```
> return string_array_proximity
> 
> ```

oops this should have been  
return string\_array\_proximity(self, other)

You get the idea anyway.

---

<div class="post-metadata">

**Author:** ![orenshani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/e47c2d/32.png) [@orenshani](https://www.ruby-forum.com/u/orenshani)\
**Post date:** [July 24, 2009, 11:41am UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630/3 "2009-07-24T11:41:27Z")

</div>

I would do a module and then mix that in to any of your required  
classes. The module has one public method, ‘proximity’ that looks at  
the class of ‘self’ and of the other object, and then decides what to do  
accordingly. The various behaviours for comparing different classes can  
be expressed through various private methods. eg

#save in a file called proximity.rb  
module Proximity  
def proximity(other)  
case [self.class, other.class]  
when [Array, Array]  
return array\_array\_proximity(self, other)  
when [Array, String] || [String, Array]  
return string\_array\_proximity  
#etc  
else  
return false #or raise  
end  
end  
end

private  
def array\_array\_proximity(arg1, arg2)  
#your logic here  
end

def string\_array\_proximity(arg1, arg2)  
#your logic here  
end

#etc  
end

Now you can include this module into the various classes - somewhere in  
your initialisation process you can do

require ‘proximity’

class Array  
include Proximity  
end

class String  
include Proximity  
end

etc

---

<div class="post-metadata">

**Author:** ![orenshani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/e47c2d/32.png) [@orenshani](https://www.ruby-forum.com/u/orenshani)\
**Post date:** [July 24, 2009, 3:11pm UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630/4 "2009-07-24T15:11:42Z")

</div>

Max W. wrote:

> Max W. wrote:
> 
> > Max W. wrote:
> > 
> > > ```
> > > return string_array_proximity
> > > 
> > > ```
> > 
> > oops this should have been  
> > return string\_array\_proximity(self, other)
> > 
> > You get the idea anyway.
> 
> oh and in case you don’t have a string comparison method yet there’s a  
> nice gem called amatch which implements many different string proximity  
> algorithms, eg levenshtein distance etc.

Max,

Many thanks for your replies.

I like your approach because it makes it easy to metacode the proximity  
module, that is to allow users to define metaobjects by something like:

class txtwords \< Factfile  
basetype Array

porximate\_to Array,Array\_Array\_proxy  
proximate\_to String,Array\_String proxy

…

So every call to the proximate\_to function will actually re-program the  
case part of the module (would appreciate any ideas about how to best  
implement that…).

Also, many thanks for the reference to the amatch module. I am quite a  
lazy person so I would be happy to re-use anything that already exists  
🙂

Best,

Oren

---

<div class="post-metadata">

**Author:** ![orenshani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/e47c2d/32.png) [@orenshani](https://www.ruby-forum.com/u/orenshani)\
**Post date:** [July 24, 2009, 11:47am UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630/5 "2009-07-24T11:47:01Z")

</div>

Max W. wrote:

> Max W. wrote:
> 
> > ```
> > return string_array_proximity
> > 
> > ```
> 
> oops this should have been  
> return string\_array\_proximity(self, other)
> 
> You get the idea anyway.

oh and in case you don’t have a string comparison method yet there’s a  
nice gem called amatch which implements many different string proximity  
algorithms, eg levenshtein distance etc.

---

<div class="post-metadata">

**Author:** ![orenshani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/e47c2d/32.png) [@orenshani](https://www.ruby-forum.com/u/orenshani)\
**Post date:** [July 24, 2009, 7:48pm UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630/6 "2009-07-24T19:48:49Z")

</div>

Kaspar S. wrote:

> > So does anyone have any other ideas for doing this kind of object-pairs  
> > dependent coding, is ther some kind of best-practice for this situation?
> 
> If there is one proximity function per valid pair, storing that  
> function/method in a specialized class is not a bad idea. Most likely  
> though you’d have some kind of default behavior for the pair proximity  
> and then some special cases depending on one, the other or both of the  
> elements of the pair.
> 
> I guess a good class design would try to capture the common cases first,  
> specializing only where needed. In the general case you might have  
> something like
> 
> class ProximityTuple  
> attr\_reader :base, :reference
> 
> # setup …
> 
> def proximity  
> if base.respond\_to? :proximity\_to  
> return base.proximity\_to(reference)  
> end
> 
> ```
> if reference.respond_to? :proximity_to
> return reference.proximity_to(base)
> end
> 
> # default behaviour
> 
> ```
> 
> end  
> end
> 
> class SpecializedTuple \< ProximityTuple
> 
> # …
> 
> def proximity  
> # special implementation  
> end  
> end
> 
> This would be customizable by either letting the default do the work, or  
> let one of the participants do the work, or the specialized tuple.
> 
> If you would care to more closely describe the kind of objects you’re  
> handling and the function(s) involved this might get simplified (again)  
> considerably. This is the best I can come up with in the abstract case  
> 😉
> 
> regards,  
> kaspar

Kaspar,

I would be happy to share more details about what I am doing with you  
and with the community but it is a little to early for that, not because  
I have something to hide, but because I don’t have much to show. So  
right now I am more interested in general approcahes and best practices,  
that will help me decide about some conceptual issues. In this context  
your answer is very helpful.

Thanks,

Oren

---

<div class="post-metadata">

**Author:** ![orenshani](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/e47c2d/32.png) [@orenshani](https://www.ruby-forum.com/u/orenshani)\
**Post date:** [July 24, 2009, 5:05pm UTC](https://www.ruby-forum.com/t/methods-depend-on-pairs-of-objects-best-parctise-pls/172630/7 "2009-07-24T17:05:48Z")

</div>

> So does anyone have any other ideas for doing this kind of object-pairs  
> dependent coding, is ther some kind of best-practice for this situation?

If there is one proximity function per valid pair, storing that  
function/method in a specialized class is not a bad idea. Most likely  
though you’d have some kind of default behavior for the pair proximity  
and then some special cases depending on one, the other or both of the  
elements of the pair.

I guess a good class design would try to capture the common cases first,  
specializing only where needed. In the general case you might have  
something like

class ProximityTuple  
attr\_reader :base, :reference

# setup …

def proximity  
if base.respond\_to? :proximity\_to  
return base.proximity\_to(reference)  
end

```
 if reference.respond_to? :proximity_to
   return reference.proximity_to(base)
 end

 # default behaviour

```

end  
end

class SpecializedTuple \< ProximityTuple

# …

def proximity  
# special implementation  
end  
end

This would be customizable by either letting the default do the work, or  
let one of the participants do the work, or the specialized tuple.

If you would care to more closely describe the kind of objects you’re  
handling and the function(s) involved this might get simplified (again)  
considerably. This is the best I can come up with in the abstract case  
😉

regards,  
kaspar
