Class: UnboundedRange

Inherits:
Range show all
Includes:
Comparable, Constants
Defined in:
app/models/unbounded_range.rb

Overview

Extention of Range class to unbounded limits Used in RegexpTree for /.*/ and /.+/ handles comparisons as UnboundedFixnum::Inf means unbounded (i.e. infinity)

Defined Under Namespace

Modules: Constants

Constant Summary

Constants included from Constants

Constants::Any_range, Constants::Any_repetition, Constants::Many_range, Constants::Once, Constants::Optional

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(min, max) ⇒ UnboundedRange

Returns a new instance of UnboundedRange.


14
15
16
17
18
19
# File 'app/models/unbounded_range.rb', line 14

def initialize(min, max)
	min=UnboundedFixnum.promote(min, -1)
	max=UnboundedFixnum.promote(max, +1)
	super(min, max)
	raise "min=#{min.inspect} must be less than or equal to max=#{max.inspect}." if min > max
end

Class Method Details

.promote(rhs) ⇒ Object

Promote (specialize inherited type)


29
30
31
32
33
34
35
# File 'app/models/unbounded_range.rb', line 29

def UnboundedRange.promote(rhs)
#	if rhs.instance_of?(UnboundedRange) then
#		self
#	elsif rhs.instance_of?(Range)
		UnboundedRange.new(UnboundedFixnum.promote(rhs.first, -1), UnboundedFixnum.promote(rhs.last, +1))
#	end #if
end

Instance Method Details

#&(rhs) ⇒ Object

intersection. If neither is a subset of the rhs return UnboundedFixnum::Inf


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'app/models/unbounded_range.rb', line 72

def &(rhs)
	lhs=self
	rhs=UnboundedRange.promote(rhs)
	min= [lhs.first, rhs.first].max
	max=if lhs.last.nil? then
		rhs.last
	else
		case lhs.last <=> rhs.last
		when 1,0
			rhs.last
		when -1
			lhs.last
		when UnboundedFixnum::Inf
			return UnboundedFixnum::Inf	
		end #case
	end #if
	UnboundedRange.new(min, max)
end

#+(rhs) ⇒ Object

calculate sum for merging sequential repetitions


65
66
67
68
69
70
# File 'app/models/unbounded_range.rb', line 65

def +(rhs)
	lhs=self
	rhs=UnboundedRange.promote(rhs)
	max=lhs.last+rhs.last
	return UnboundedRange.new(lhs.first+rhs.first, max)
end

#<=>(rhs) ⇒ Object


50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/models/unbounded_range.rb', line 50

def <=>(rhs)
	lhs=self
	rhs=UnboundedRange.promote(rhs)
 	if eql?(rhs) then
		return 0
	elsif lhs.first<=rhs.first && (rhs.last<=lhs.last) then
		return 1
	elsif rhs.first<=lhs.first && (lhs.last<=rhs.last) then
		return -1
	else
		return nil
	end #if

end

#==(rhs) ⇒ Object

called by assert_equal No coercion of arguments like in Numeric


47
48
49
# File 'app/models/unbounded_range.rb', line 47

def ==(rhs)
	eql?(rhs)
end

#eql?(rhs) ⇒ Boolean

promote

Returns:

  • (Boolean)

36
37
38
39
40
41
42
43
44
# File 'app/models/unbounded_range.rb', line 36

def eql?(rhs)
	lhs=self
	rhs=UnboundedRange.promote(rhs)
 	if lhs.first.to_i==rhs.first.to_i && lhs.last.to_i==rhs.last.to_i then
		true
	else
		false
	end #if
end

#|(rhs) ⇒ Object

Union. Unlike set union disjoint sets return a spanning set.


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'app/models/unbounded_range.rb', line 91

def |(rhs)
	lhs=self
	rhs=UnboundedRange.promote(rhs)
	min= [lhs.first, rhs.first].min
	max=if lhs.last.nil? then
		UnboundedFixnum::Inf
	else
		case lhs.last <=> rhs.last
		when 1,0
			lhs.last
		when -1
			rhs.last
		when UnboundedFixnum::Inf
			max=[lhs.last, rhs.last].max	
		end #case
	end #if
	UnboundedRange.new(min, max)
end