File: extending_behavior.out.rb

package info (click to toggle)
ruby-algebrick 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 276 kB
  • sloc: ruby: 1,614; makefile: 3
file content (62 lines) | stat: -rw-r--r-- 1,951 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Maybe = Algebrick.type do
  variants None = atom,
           Some = type { fields Object }
end                                                # => Maybe(None | Some)

# Types can be extended with usual syntax for modules and using Ruby supports module reopening.
module Maybe
  def maybe(&block)
    case self
    when None
    when Some
      block.call value
    end
  end
end 

# #maybe method is defined on both values (None, Some) of Maybe.
None.maybe { |_| raise 'never ever happens' }      # => nil
# Block is called with the value.
Some[1].maybe { |v| v*2 }                          # => 2

# It also works as expected when modules like Comparable are included.
Season = Algebrick.type do
  variants Spring = atom,
           Summer = atom,
           Autumn = atom,
           Winter = atom
end                                                # => Season(Spring | Summer | Autumn | Winter)

module Season
  include Comparable
  ORDER = Season.variants.each_with_index.each_with_object({}) { |(season, i), h| h[season] = i }

  def <=>(other)
    Type! other, Season
    ORDER[self] <=> ORDER[other]
  end
end 

Quarter = Algebrick.type do
  fields! year: Integer, season: Season
end                                                # => Quarter(year: Integer, season: Season)

module Quarter
  include Comparable

  def <=>(other)
    Type! other, Quarter
    [year, season] <=> [other.year, other.season]
  end
end 

# Now Quarters and Seasons can be compared as expected.
[Winter, Summer, Spring, Autumn].sort              # => [Spring, Summer, Autumn, Winter]
Quarter[2013, Spring] < Quarter[2013, Summer]      # => true
Quarter[2014, Spring] > Quarter[2013, Summer]      # => true
Quarter[2014, Spring] == Quarter[2014, Spring]     # => true
[Quarter[2013, Spring], Quarter[2013, Summer], Quarter[2014, Spring]].sort
    # => [Quarter[year: 2013, season: Spring], Quarter[year: 2013, season: Summer], Quarter[year: 2014, season: Spring]]