case_class 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/README ADDED
@@ -0,0 +1,28 @@
1
+ = case_class
2
+
3
+ Scala-like case classes for Ruby
4
+
5
+ == SYNOPSIS:
6
+
7
+ require "case_class"
8
+ include CaseClass
9
+
10
+ Number = Case[:n]
11
+ Sum = Case[:e1, :e2]
12
+
13
+ # evaluation with pattern matching
14
+ def eval(n)
15
+ case n
16
+ when Sum[e1 = _, e2 = _] then eval(e1) + eval(e2)
17
+ when Number[n = _] then n
18
+ end
19
+ end
20
+
21
+ # (1 + 2) + (3 + 4) => 10
22
+ expr = Sum[Sum[Number[1], Number[2]], Sum[Number[3], Number[4]]]
23
+ p eval(expr) #=> 10
24
+
25
+ == LICENSE:
26
+
27
+ Copyright:: Yusuke Endoh <mame@tsg.ne.jp>
28
+ License:: Ruby's
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "case_class"
8
+ gem.summary = %Q{Scala-like case classes for Ruby}
9
+ gem.description = %Q{This provides Scala-like case classes for Ruby. You can enjoy pattern matching with place holders.}
10
+ gem.email = "mame@tsg.ne.jp"
11
+ gem.homepage = "http://github.com/mame/case_class"
12
+ gem.authors = ["Yusuke Endoh"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/test_*.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :test => :check_dependencies
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "case_class #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,13 @@
1
+ require "case_class"
2
+ include CaseClass
3
+
4
+ # create placeholder (a.k.a. promise or future)
5
+ x = _
6
+ a = [1, x, 2, x, 3, x]
7
+
8
+ p a #=> [1, _promise_, 2, _promise_, 3, _promise_]
9
+
10
+ # fulfill promise by 42 (not assign)
11
+ x === 42
12
+
13
+ p a #=> [1, 42, 2, 42, 3, 42]
data/examples/expr.rb ADDED
@@ -0,0 +1,19 @@
1
+ require "case_class"
2
+ include CaseClass
3
+
4
+ # data Expr = Number Int | Sum Expr Expr
5
+
6
+ Number = Case[:n]
7
+ Sum = Case[:e1, :e2]
8
+
9
+ # evaluation with pattern matching
10
+ def eval(n)
11
+ case n
12
+ when Sum[e1 = _, e2 = _] then eval(e1) + eval(e2)
13
+ when Number[n = _] then n
14
+ end
15
+ end
16
+
17
+ # (1 + 2) + (3 + 4)
18
+ expr = Sum[Sum[Number[1], Number[2]], Sum[Number[3], Number[4]]]
19
+ p eval(expr) #=> 10
@@ -0,0 +1,85 @@
1
+ require "case_class"
2
+ include CaseClass
3
+
4
+ # translated from http://www.cs.kent.ac.uk/people/staff/smk/redblack/
5
+ module RedBlackTree
6
+ # data RB a = E | T Color (RB a) a (RB a)
7
+ E = Case[]
8
+ T = Case[:c, :l, :v, :r]
9
+
10
+ def insert(x, t)
11
+ T[_,a=_,z=_,b=_] === insert0(x, t)
12
+ T[:B,a,z,b]
13
+ end
14
+
15
+ def insert0(x, t)
16
+ case t
17
+ when E; T[:R,E,x,E]
18
+ when T[:B,a=_,y=_,b=_]
19
+ case
20
+ when x<y; balance(insert0(x, a), y, b)
21
+ when x>y; balance(a, y, insert0(x, b))
22
+ else t
23
+ end
24
+ when T[:R,a=_,y=_,b=_]
25
+ case
26
+ when x<y; T[:R, insert0(x, a), y, b]
27
+ when x>y; T[:R, a, y, insert0(x, b)]
28
+ else t
29
+ end
30
+ end
31
+ end
32
+
33
+ def member(x, t)
34
+ case t
35
+ when T[_, a=_, y=_, b=_]
36
+ case
37
+ when x<y; member(x, a)
38
+ when x>y; member(x, b)
39
+ else true
40
+ end
41
+ else
42
+ false
43
+ end
44
+ end
45
+
46
+ def balance(l, v, r)
47
+ case [l, v, r]
48
+ when [T[:R,T[:R,a=_,x=_,b=_],y=_,c=_],z=_,d=_]; T[:R,T[:B,a,x,b],y,T[:B,c,z,d]]
49
+ when [T[:R,a=_,x=_,T[:R,b=_,y=_,c=_]],z=_,d=_]; T[:R,T[:B,a,x,b],y,T[:B,c,z,d]]
50
+ when [T[:R,a=_,x=_,b=_],y=_,T[:R,c=_,z=_,d=_]]; T[:R,T[:B,a,x,b],y,T[:B,c,z,d]]
51
+ when [a=_,x=_,T[:R,T[:R,b=_,y=_,c=_],z=_,d=_]]; T[:R,T[:B,a,x,b],y,T[:B,c,z,d]]
52
+ when [a=_,x=_,T[:R,b=_,y=_,T[:R,c=_,z=_,d=_]]]; T[:R,T[:B,a,x,b],y,T[:B,c,z,d]]
53
+ when [a=_,x=_,b=_]; T[:B,a,x,b]
54
+ end
55
+ end
56
+
57
+ # # balance with no pattern matching
58
+ # def balance(l, v, r)
59
+ # case
60
+ # when T===l && l.c===:R && T===l.l && l.l.c===:R
61
+ # T[:R,T[:B,l.l.l,l.l.v,l.l.r],l.v,T[:B,l.r,v,r]]
62
+ # when T===l && l.c===:R && T===l.r && l.r.c===:R
63
+ # T[:R,T[:B,l.l,l.v,l.r.l],l.r.v,T[:B,l.r.r,v,r]]
64
+ # when T===l && l.c===:R && T===r && r .c===:R
65
+ # T[:R,T[:B,l.l,l.v,l.r],v,T[:B,r.l,r.v,r.r]]
66
+ # when T===r && r.c===:R && T===r.l && r.l.c===:R
67
+ # T[:R,T[:B,l,v,r.l.l],r.l.v,T[:B,r.l.r,r.v,r.r]]
68
+ # when T===r && r.c===:R && T===r.r && r.r.c===:R
69
+ # T[:R,T[:B,l,v,r.l],r.v,T[:B,r.r.l,r.r.v,r.r.r]]
70
+ # else T[:B,l,v,r]
71
+ # end
72
+ # end
73
+ end
74
+
75
+ include RedBlackTree
76
+
77
+ tree = E
78
+ (1..10).to_a.shuffle.each do |x|
79
+ tree = insert(x, tree)
80
+ end
81
+
82
+ p member( 5, tree) #=> true
83
+ p member(11, tree) #=> false
84
+ p member( 0, tree) #=> false
85
+ p tree
data/lib/case_class.rb ADDED
@@ -0,0 +1,47 @@
1
+ require "delegate"
2
+
3
+ module CaseClass
4
+ class PlaceHolder < SimpleDelegator
5
+ def initialize
6
+ class << self
7
+ def ==(obj)
8
+ obj = obj.__getobj__ while PlaceHolder === obj
9
+ class << self
10
+ remove_method(:==)
11
+ remove_method(:===)
12
+ remove_method(:inspect)
13
+ end
14
+ __setobj__(obj)
15
+ true
16
+ end
17
+
18
+ alias === ==
19
+
20
+ def inspect
21
+ "_promise_"
22
+ end
23
+ end
24
+
25
+ super(nil)
26
+ end
27
+ end
28
+
29
+ class Case < Struct
30
+ def ===(obj)
31
+ obj = obj.__getobj__ while PlaceHolder === obj
32
+ super
33
+ end
34
+
35
+ def self.[](*ary)
36
+ if ary.size >= 1
37
+ new(*ary)
38
+ else
39
+ new(:dummy)[nil]
40
+ end
41
+ end
42
+ end
43
+
44
+ def _
45
+ PlaceHolder.new
46
+ end
47
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'case_class'
7
+
8
+ class Test::Unit::TestCase
9
+ end
@@ -0,0 +1,22 @@
1
+ require "helper"
2
+
3
+ class TestCaseClass < Test::Unit::TestCase
4
+ def test_placeholder
5
+ x = CaseClass::PlaceHolder.new
6
+ assert_equal("_promise_", x.inspect)
7
+ assert_equal(true, x === 42)
8
+ assert_equal("42", x.inspect)
9
+ end
10
+
11
+ Foo = CaseClass::Case[:x, :y, :z]
12
+ def test_case
13
+ foo = Foo[1, 2, 3]
14
+ x = CaseClass::PlaceHolder.new
15
+ y = CaseClass::PlaceHolder.new
16
+ z = CaseClass::PlaceHolder.new
17
+ Foo[x, y, z] === Foo[1, 2, 3]
18
+ assert_equal(1, x)
19
+ assert_equal(2, y)
20
+ assert_equal(3, z)
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: case_class
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Yusuke Endoh
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-22 00:00:00 +09:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: This provides Scala-like case classes for Ruby. You can enjoy pattern matching with place holders.
22
+ email: mame@tsg.ne.jp
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README
29
+ files:
30
+ - .document
31
+ - .gitignore
32
+ - README
33
+ - Rakefile
34
+ - VERSION
35
+ - examples/example.rb
36
+ - examples/expr.rb
37
+ - examples/rbtree.rb
38
+ - lib/case_class.rb
39
+ - test/helper.rb
40
+ - test/test_case_class.rb
41
+ has_rdoc: true
42
+ homepage: http://github.com/mame/case_class
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options:
47
+ - --charset=UTF-8
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.7
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Scala-like case classes for Ruby
73
+ test_files:
74
+ - test/helper.rb
75
+ - test/test_case_class.rb
76
+ - examples/rbtree.rb
77
+ - examples/expr.rb
78
+ - examples/example.rb