# Code to DRY

**URL:** <https://www.ruby-forum.com/t/code-to-dry/118780>\
**Category:** Ruby\
**Created:** [October 30, 2007, 9:31pm UTC](https://www.ruby-forum.com/t/code-to-dry/118780 "2007-10-30T21:31:12Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 30, 2007, 9:31pm UTC](https://www.ruby-forum.com/t/code-to-dry/118780/1 "2007-10-30T21:31:12Z")

</div>

This is a simplified version of the problem I have. I work with  
“ordered” classes, i.e. having a method a.le?(b) (le = lower or equal).  
But I want two constants MIN and MAX, same for all classes, with  
MIN.le?(a) == true, a.le?(MAX) == true, a.le?(MIN) only if a == MIN and  
MAX.le?(a) only if a == MAX. Moreover, I want a default a.le?(b) when  
le? is not defined for a.Class.

This is a possibility

class MaxClass  
def le?(other); other == self ; end  
end  
class MinClass  
def le?(other); true ; end  
end  
MAX = MaxClass.new  
MIN = MinClass.new

def method\_missing(name, \*args)  
if name == “le?”  
case args[0]  
when MAX : true  
when MIN : false  
else  
# real thing for default  
end  
else  
super  
end  
end

class Klass1  
def le?(other)  
case other  
when MAX : true  
when MIN : false  
else  
# real thing for Klass1  
end  
end  
end

class Klass2  
def le?(other)  
case other  
when MAX : true  
when MIN : false  
else  
# real thing for Klass1  
end  
end  
end

and so on

Obviously not DRY !  
Suggestions ?

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 30, 2007, 10:01pm UTC](https://www.ruby-forum.com/t/code-to-dry/118780/2 "2007-10-30T22:01:26Z")

</div>

How about:

module Ordered  
def le?(other)  
case other  
when MAX : true  
when MIN : false  
else  
less\_than\_or\_equal? other  
end  
end  
end

class Klass1  
include Ordered

def less\_than\_or\_equal? other  
# stuff  
end  
end

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 31, 2007, 1:19am UTC](https://www.ruby-forum.com/t/code-to-dry/118780/3 "2007-10-31T01:19:02Z")

</div>

Quoth Martin DeMello:

> end  
> end
> 
> class Klass1  
> include Ordered
> 
> def less\_than\_or\_equal? other  
> # stuff  
> end  
> end

And instead of #le?, why not #\<, #==, #\>, #\<=\>?

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 31, 2007, 8:23am UTC](https://www.ruby-forum.com/t/code-to-dry/118780/4 "2007-10-31T08:23:38Z")

</div>

Martin DeMello wrote:

> How about:

> end

Thanks Martin, clean and simple.

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 31, 2007, 8:24am UTC](https://www.ruby-forum.com/t/code-to-dry/118780/5 "2007-10-31T08:24:54Z")

</div>

Konrad M. wrote:

> Quoth Martin DeMello:
> 
> > end  
> > end
> > 
> > class Klass1  
> > include Ordered
> > 
> > def less\_than\_or\_equal? other  
> > # stuff  
> > end  
> > end
> 
> And instead of #le?, why not #\<, #==, #\>, #\<=\>?

#\< looks good. Thanks.

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 31, 2007, 11:33am UTC](https://www.ruby-forum.com/t/code-to-dry/118780/6 "2007-10-31T11:33:28Z")

</div>

2007/10/31, Michel D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > > end  
> > > end
> > 
> > And instead of #le?, why not #\<, #==, #\>, #\<=\>?
> 
> #\< looks good. Thanks.

Also keep attention to module Comparable  
[http://www.ruby-doc.org/core/classes/Comparable.html](http://www.ruby-doc.org/core/classes/Comparable.html)

Basically you need to only implement \<=\> and get all other operators for  
free.

Btw, what do you need min and max for?

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 31, 2007, 11:56am UTC](https://www.ruby-forum.com/t/code-to-dry/118780/7 "2007-10-31T11:56:30Z")

</div>

Robert K. wrote:

> 2007/10/31, Michel D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > > > end  
> > > > end
> > > 
> > > And instead of #le?, why not #\<, #==, #\>, #\<=\>?
> > 
> > #\< looks good. Thanks.
> 
> Also keep attention to module Comparable  
> [module Comparable - RDoc Documentation](http://www.ruby-doc.org/core/classes/Comparable.html)
> 
> Basically you need to only implement \<=\> and get all other operators for  
> free.
> 
> Btw, what do you need min and max for?
> 
> Kind regards
> 
> robert

Robert,

Actually, I have partial orders (“prÃ©ordre” in french) and not orders  
(“ordre total” in french), so \<=\> does not work well. For instance, you  
can have a.le?(b) and b.le?(a), but not a = b. Or neither a.le?(b), nor  
b.le?(a). For instance a.lt?(b) is “a.le?(b) and not b.le?(a)” but not  
“a.le?(B) and a != b”.

I need min and max for semantic reasons, analogous to Scott’s semantics  
for programming languages : ‘min’ is something like ‘undefined’  
(definitely less than ‘defined with value nil’ for instance) and ‘max’  
is something like ‘overdefined’ or ‘impossible’. All this for some try  
at a “fuzzy knowledge” management program…which actually works quite  
well!

Best,  
Michel

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 31, 2007, 1:05pm UTC](https://www.ruby-forum.com/t/code-to-dry/118780/8 "2007-10-31T13:05:01Z")

</div>

2007/10/31, Michel D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > [module Comparable - RDoc Documentation](http://www.ruby-doc.org/core/classes/Comparable.html)  
> > Robert,
> 
> Actually, I have partial orders (“préordre” in french) and not orders  
> (“ordre total” in french), so \<=\> does not work well. For instance, you  
> can have a.le?(b) and b.le?(a), but not a = b. Or neither a.le?(b), nor  
> b.le?(a). For instance a.lt?(b) is “a.le?(b) and not b.le?(a)” but not  
> “a.le?(B) and a != b”.

Ah, I see. I wasn’t aware of this. In that case it’s probably also  
not a good idea to use \<, \> etc. to avoid confusion. Do you use some  
kind of topological sort then?

> I need min and max for semantic reasons, analogous to Scott’s semantics  
> for programming languages : ‘min’ is something like ‘undefined’  
> (definitely less than ‘defined with value nil’ for instance) and ‘max’  
> is something like ‘overdefined’ or ‘impossible’. All this for some try  
> at a “fuzzy knowledge” management program…which actually works quite  
> well!

I still do not know how you use min and max but it certainly sounds  
interesting! 🙂

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![micheldogger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b5e925/32.png) [@micheldogger](https://www.ruby-forum.com/u/micheldogger)\
**Post date:** [October 31, 2007, 4:00pm UTC](https://www.ruby-forum.com/t/code-to-dry/118780/9 "2007-10-31T16:00:27Z")

</div>

Robert K. wrote:

> 2007/10/31, Michel D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):  
> Ah, I see. I wasn’t aware of this. In that case it’s probably also  
> not a good idea to use \<, \> etc. to avoid confusion. Do you use some  
> kind of topological sort then?

No, I only use it to find, if any, a “piece of knowledge” b with  
a.le?(b).  
Toy examples :  
“birthday” \<= “birthday John in March” \<= “birthday John 15th March”…  
So, for Persons : MIN \<= John \<= John D. \<= John D. phone=12345 \<=…  
for Dates “MIN \<= March” \<= “15th March” \<= 15th March 9pm …

> I still do not know how you use min and max but it certainly sounds  
> interesting! 🙂  
> See above for MIN. MAX happens for instance when you freeze a knowledge  
> and then modify it. Or when you know too much : “birthday 15th March and  
> 2d April”…

All the best,

Michel
