ludy 0.1.1 → 0.1.2

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/CHANGES CHANGED
@@ -1,5 +1,11 @@
1
1
  = ludy changes history
2
2
 
3
+ == ludy 0.1.2, 2008.01.17
4
+
5
+ * aims to add functional stuffs, list comprehension is working in progress
6
+ * Paginator series are added.
7
+ * more rdocs are added.
8
+
3
9
  == ludy 0.1.1, 2008.01.10
4
10
 
5
11
  * add Array#tail and Array#map_with_index to make the task of
data/Manifest.txt CHANGED
@@ -30,6 +30,7 @@ lib/ludy/deprecated/this.rb
30
30
  lib/ludy/deprecated/untranspose.rb
31
31
  lib/ludy/deprecated/unzip.rb
32
32
  lib/ludy/dices.rb
33
+ lib/ludy/helpers/check_box.rb
33
34
  lib/ludy/kernel.rb
34
35
  lib/ludy/kernel/defun.rb
35
36
  lib/ludy/kernel/ergo.rb
@@ -40,7 +41,9 @@ lib/ludy/kernel/public_send.rb
40
41
  lib/ludy/kernel/singleton_method.rb
41
42
  lib/ludy/kernel/tap.rb
42
43
  lib/ludy/lazy.rb
44
+ lib/ludy/list.rb
43
45
  lib/ludy/message_dispatcher.rb
46
+ lib/ludy/paginator.rb
44
47
  lib/ludy/pattern_matcher.rb
45
48
  lib/ludy/proc.rb
46
49
  lib/ludy/proc/bind.rb
@@ -91,6 +94,7 @@ test/test_defun.rb
91
94
  test/test_dices.rb
92
95
  test/test_kernel.rb
93
96
  test/test_lazy.rb
97
+ test/test_paginator.rb
94
98
  test/test_proc.rb
95
99
  test/test_symbol.rb
96
100
  test/test_variable.rb
data/README CHANGED
@@ -1,4 +1,4 @@
1
- = ludy 0.1.1
1
+ = ludy 0.1.2
2
2
  by Lin Jen-Shin (a.k.a. godfat 真常)
3
3
  strip any number: 18god29fat7029 (at] godfat32 -dooot- 20org
4
4
  http://ludy.rubyforge.org
@@ -6,13 +6,14 @@
6
6
 
7
7
  == DESCRIPTION:
8
8
 
9
- Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library.
9
+ Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library, especially for functional programming.
10
10
 
11
11
  == FEATURES:
12
12
 
13
- * ludy standard library extension
14
- * puzzle_generator
15
- * c++ erb meta-programming
13
+ 1. ludy standard library extension, especially for functional programming.
14
+ 2. rails/array paginator, included since 0.1.2
15
+ 3. c++ erb meta-programming, included since 0.1.0
16
+ 4. puzzle_generator, included since 0.0.8
16
17
 
17
18
  == SYNOPSIS:
18
19
 
@@ -74,6 +75,28 @@ y_combinator:
74
75
  }]
75
76
  assert_equal(3628800, fact[10])
76
77
 
78
+ paginator:
79
+ pager = Ludy::RailsPaginator.new(Topic)
80
+ pager = Ludy::ArrayPaginator.new(TestPaginator.data)
81
+ # or the most flexible paginator:
82
+ pager = Ludy::Paginator.new(
83
+ lambda{ |offset, per_page|
84
+ # if for rails,
85
+ # Data.find :all, :offset => offset, :limit => per_page
86
+ TestPaginator.data[offset, per_page]
87
+ }, lambda{
88
+ # if for rails,
89
+ # Data.count
90
+ TestPaginator.data.size
91
+ })
92
+ pager.per_page = 10
93
+
94
+ pager.page(1)
95
+ pager[1] # same as above
96
+ pager.page(2).next_page.prev_page.each{|e| e} # you can enumerate
97
+ pager[3].map{|e| e*2}
98
+ pager.size # number of pages
99
+ pager.inject(0){|r, i| r += i.inject &:+ } # total sum of all data
77
100
 
78
101
  ludy tasks:
79
102
 
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ task :default do
12
12
  end
13
13
 
14
14
  PROJ.name = 'ludy'
15
- PROJ.summary = 'Aims to extend Ruby standard library, providing some useful tools that\'s not existed in the standard library.'
15
+ PROJ.summary = 'Aims to extend Ruby standard library, providing some useful tools that\'s not existed in the standard library, especially for functional programming.'
16
16
  PROJ.authors = 'Lin Jen-Shin (a.k.a. godfat 真常)'
17
17
  PROJ.email = 'strip any number: 18god29fat7029 (at] godfat32 -dooot- 20org'
18
18
  PROJ.url = 'http://ludy.rubyforge.org/'
@@ -20,7 +20,7 @@ PROJ.description = paragraphs_of('README', 1).join("\n\n")
20
20
  PROJ.changes = paragraphs_of('CHANGES', 0..1).join("\n\n")
21
21
  PROJ.rubyforge_name = 'ludy'
22
22
 
23
- PROJ.version = '0.1.1'
23
+ PROJ.version = '0.1.2'
24
24
  PROJ.exclude << '.DS_Store' << '^tmp'
25
25
  PROJ.dependencies << 'rake'
26
26
 
data/TODO CHANGED
@@ -3,3 +3,10 @@
3
3
  * chain travel
4
4
  * method hook
5
5
  * more rdoc
6
+
7
+ * list comprehension List[lambda{|x,y|[x,y*2]}, (0..1), (2..3), lambda{|x,y|x!=y}]
8
+ * better namespace
9
+ * extract Array's methods to Enumerable
10
+
11
+ * table showing, with pad.
12
+ * rails multiple layout
@@ -0,0 +1,24 @@
1
+
2
+ module Ludy
3
+ # check box helper for html view generation.
4
+ # require 'ludy/helpers/check_box'
5
+ # module ApplicationHelper
6
+ # include Ludy::CheckBox
7
+ # end
8
+ module CheckBox
9
+ # create a link respond to onclick and <em>check</em> all check_box for all
10
+ # specified elements.
11
+ # id_and_or_class, e.g., #form_inviting input.check_box_friend
12
+ # ^^^^^id elements^^^ ^^^^^^^^^^^class
13
+ def check_all text, id_and_or_class
14
+ "<a href=\"#\" onclick=\"$$('#{id_and_or_class}').each(function(box){box.checked='checked'});return false;\">#{text}</a>"
15
+ end
16
+ # create a link respond to onclick and <em>uncheck</em> all check_box for all
17
+ # specified elements.
18
+ # id_and_or_class, e.g., #form_inviting input.check_box_friend
19
+ # ^^^^^id elements^^^ ^^^^^^^^^^^class
20
+ def uncheck_all text, id_and_or_class
21
+ "<a href=\"#\" onclick=\"$$('#{id_and_or_class}').each(function(box){box.checked=''});return false;\">#{text}</a>"
22
+ end
23
+ end
24
+ end
@@ -1,6 +1,6 @@
1
1
 
2
- module Kernel
3
- if RUBY_VERSION < '1.9.0'
2
+ if RUBY_VERSION < '1.9.0'
3
+ module Kernel
4
4
  # it would be defined if RUBY_VERSION < '1.9.0', see rdoc in ruby 1.9
5
5
  def public_send msg, *args, &block
6
6
  if self.respond_to? msg
data/lib/ludy/list.rb ADDED
@@ -0,0 +1,21 @@
1
+
2
+ module Ludy
3
+ # fib = 0 : 1 : [x+y | (x, y) <- zip fib (tail fib)]
4
+ # combos = List[->(x,y){[x,y]}, 0..1, 2..3]
5
+ class List # :nodoc:
6
+ private :initialize
7
+ class << self
8
+ def [] target, *args
9
+ raise ArgumentError.new("you need at least #{target.arity} arguments(sources) for #{target}") if args.size < target.arity
10
+ sources = args[0...target.arity]
11
+ conditions = args[target.arity..-1]
12
+ create_array sources, conditions
13
+ end
14
+
15
+ private
16
+ def create_array sources, conditions
17
+ sources.traspose.flatten
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,118 @@
1
+
2
+ require 'ludy/kernel/public_send' if RUBY_VERSION < '1.9.0'
3
+
4
+ module Ludy
5
+ # which was produced by Paginator#page / Paginator#[],
6
+ # representing page that contained target data.
7
+ # it would use lazy fetching, whenever you need the data,
8
+ # the fetcher would be invoked that time. whenever the data
9
+ # was fetched, it won't fetch again. it you need refetch,
10
+ # call Page#fetch
11
+ class Page
12
+ undef_method :to_a if RUBY_VERSION < '1.9.0'
13
+ attr_reader :pager
14
+ # don't create a page instance yourself unless you have to
15
+ def initialize pager, page; @pager, @page = pager, page; end
16
+ # return the page instance next to this page
17
+ def next_page; @pager.page(@page+1); end
18
+ # return the page instance prev to this page
19
+ def prev_page; @pager.page(@page-1); end
20
+ # if the page numbers and the pagers are equal,
21
+ # then the pages are equal.
22
+ def == rhs
23
+ @page == rhs.instance_variable_get('@page' ) and
24
+ @pager == rhs.instance_variable_get('@pager')
25
+ end
26
+ # explicitly fetch the data from pager
27
+ def fetch; @data = @pager.fetcher[@pager.offset(@page), @pager.per_page]; end
28
+ # get the data fetched from pager
29
+ def data; @data ||= fetch; end
30
+ # any other method call would delegate to the data,
31
+ # e.g., each, to_a, map, first, method_you_defined, etc.
32
+ def method_missing msg, *args, &block
33
+ self.data.public_send msg, *args, &block
34
+ end
35
+ end
36
+ # paginator is something help you paginate the data,
37
+ # through the fetcher and counter you pass in.
38
+ # e.g., for a array, the fetcher would be array[offset, per_page],
39
+ # the counter would be array.size. and for rails' model,
40
+ # fetcher would be Model.find :all, :offset => offset, :limit => per_page.
41
+ # see ArrayPaginator and RailsPaginator, if you just simply need them or
42
+ # have a look at the source code for example usage for Paginator.
43
+ class Paginator
44
+ include Enumerable
45
+ attr_accessor :per_page, :fetcher, :counter
46
+ # fetcher is function that fetch the data,
47
+ # counter is function that count the data.
48
+ # the default per_page is 20. you can reset per_page property later.
49
+ def initialize fetcher, counter
50
+ @per_page = 20
51
+ @fetcher = fetcher
52
+ @counter = counter
53
+ end
54
+ # if two paginators are equal, then the properties of
55
+ # per_page, fetcher, counter are all equal.
56
+ def == rhs
57
+ self.per_page == rhs.per_page and
58
+ self.fetcher == rhs.fetcher and
59
+ self.counter == rhs.counter
60
+ end
61
+ # for each page...
62
+ def each; 1.upto(size){ |i| yield page(i) }; end
63
+ # return all pages in an array
64
+ def to_a; map{|e|e}; end
65
+ alias_method :pages, :to_a
66
+ # create page instance by page number.
67
+ # if page number you specified was not existed,
68
+ # nil would be returned. note, page start at 1, not zero.
69
+ def page page
70
+ offset = (page-1)*@per_page
71
+ size = @counter.call
72
+ return nil unless page > 0 and offset <= size
73
+ Page.new self, page
74
+ end
75
+ # return the number of pages
76
+ def size
77
+ (@counter.call/@per_page.to_f).ceil
78
+ end
79
+ alias_method :[], :page
80
+ # get the offset property about the page.
81
+ # it is simply (page-1)*@per_page
82
+ def offset page
83
+ (page-1)*@per_page
84
+ end
85
+ end
86
+ # rails paginator was provided for convenience,
87
+ # it wraps Paginator for you, and you can just pass the model class to it.
88
+ # you don't have to care about the fetcher and counter.
89
+ # additionally, you can pass other options to rails paginator,
90
+ # they would be used in find options. e.g.,
91
+ # RailsPaginator.new Model, :order => 'created_at DESC'
92
+ # would invoke Model.find :all, :offset => ?, :limit => ?, order => 'created_at DESC'
93
+ class RailsPaginator < Paginator
94
+ attr_reader :model_class
95
+ def initialize model_class, opts = {}
96
+ @model_class = model_class
97
+ super(lambda{ |offset, per_page|
98
+ @model_class.find :all, opts.merge(:offset => offset, :limit => per_page)
99
+ }, lambda{
100
+ @model_class.count
101
+ })
102
+ end
103
+ end
104
+ # array paginator would just simply assume your data is an array,
105
+ # and create pages simply for your_data[offset, per_page]
106
+ # if your data is much more complex, use Paginator instead of this
107
+ class ArrayPaginator < Paginator
108
+ attr_reader :data
109
+ def initialize data
110
+ @data = data
111
+ super(lambda{ |offset, per_page|
112
+ @data[offset, per_page]
113
+ }, lambda{
114
+ @data.size
115
+ })
116
+ end
117
+ end
118
+ end
@@ -1,6 +1,6 @@
1
1
 
2
- class Symbol
3
- if RUBY_VERSION < '1.9.0'
2
+ if RUBY_VERSION < '1.9.0'
3
+ class Symbol
4
4
  # it would be defined if RUBY_VERSION < '1.9.0', see rdoc in ruby 1.9
5
5
  def to_proc; lambda{ |*args| args.shift.__send__ self, *args }; end
6
6
  end
data/spec/ludy_spec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  # bowling.rb
3
- class Bowling
3
+ class Bowling # :nodoc:
4
4
  def hit(pins)
5
5
  end
6
6
 
@@ -0,0 +1,60 @@
1
+
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ludy/test/helper')
3
+ require 'ludy/paginator'
4
+ require 'ludy/symbol/to_proc' if RUBY_VERSION < '1.9.0'
5
+
6
+ class TestPaginator < Test::Unit::TestCase
7
+ def self.data; @data ||= (0..100).to_a; end
8
+ def for_pager pager
9
+ # assume data.size is 101, data is [0,1,2,3...]
10
+ pager.per_page = 10
11
+ assert_equal 11, pager.size
12
+
13
+ assert_nil pager[0]
14
+ assert_equal((0..9).to_a, pager.page(1).to_a)
15
+ assert_equal((10..19).to_a, pager[2].to_a)
16
+ assert_equal(20, pager.page(3).first)
17
+ assert_equal((90..99).to_a, pager[10].to_a)
18
+ assert_equal([100], pager.page(11).to_a)
19
+ assert_nil(pager.page(12))
20
+
21
+ assert_equal(pager[1], pager[2].prev_page)
22
+ assert_equal(pager.page(11), pager[10].next_page)
23
+ assert_nil(pager[1].prev_page)
24
+ assert_nil(pager[10].next_page.next_page)
25
+
26
+ assert_equal pager[4].data, pager[4].fetch
27
+ assert_equal(pager[1], pager.pages.first)
28
+ assert_equal(pager[2], pager.to_a[1])
29
+ assert_equal(5050, pager.inject(0){|r, i| r += i.inject(&:+) })
30
+ end
31
+ def test_basic
32
+ pager = Ludy::Paginator.new(
33
+ lambda{ |offset, per_page|
34
+ # if for rails,
35
+ # Data.find :all, :offset => offset, :limit => per_page
36
+ TestPaginator.data[offset, per_page]
37
+ }, lambda{
38
+ # if for rails,
39
+ # Data.count
40
+ TestPaginator.data.size
41
+ })
42
+ for_pager pager
43
+ end
44
+ class Topic
45
+ class << self
46
+ def count
47
+ 101
48
+ end
49
+ def find all, opts = {}
50
+ TestPaginator.data[opts[:offset], opts[:limit]]
51
+ end
52
+ end
53
+ end
54
+ def test_for_rails
55
+ for_pager Ludy::RailsPaginator.new(Topic)
56
+ end
57
+ def test_for_array
58
+ for_pager Ludy::ArrayPaginator.new(TestPaginator.data)
59
+ end
60
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ludy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Lin Jen-Shin (a.k.a. godfat \xE7\x9C\x9F\xE5\xB8\xB8)"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-01-10 00:00:00 +08:00
12
+ date: 2008-01-17 00:00:00 +08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -21,7 +21,7 @@ dependencies:
21
21
  - !ruby/object:Gem::Version
22
22
  version: "0"
23
23
  version:
24
- description: "== DESCRIPTION: Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library."
24
+ description: "== DESCRIPTION: Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library, especially for functional programming."
25
25
  email: "strip any number: 18god29fat7029 (at] godfat32 -dooot- 20org"
26
26
  executables:
27
27
  - ludy
@@ -75,6 +75,7 @@ files:
75
75
  - lib/ludy/deprecated/untranspose.rb
76
76
  - lib/ludy/deprecated/unzip.rb
77
77
  - lib/ludy/dices.rb
78
+ - lib/ludy/helpers/check_box.rb
78
79
  - lib/ludy/kernel.rb
79
80
  - lib/ludy/kernel/defun.rb
80
81
  - lib/ludy/kernel/ergo.rb
@@ -85,7 +86,9 @@ files:
85
86
  - lib/ludy/kernel/singleton_method.rb
86
87
  - lib/ludy/kernel/tap.rb
87
88
  - lib/ludy/lazy.rb
89
+ - lib/ludy/list.rb
88
90
  - lib/ludy/message_dispatcher.rb
91
+ - lib/ludy/paginator.rb
89
92
  - lib/ludy/pattern_matcher.rb
90
93
  - lib/ludy/proc.rb
91
94
  - lib/ludy/proc/bind.rb
@@ -136,6 +139,7 @@ files:
136
139
  - test/test_dices.rb
137
140
  - test/test_kernel.rb
138
141
  - test/test_lazy.rb
142
+ - test/test_paginator.rb
139
143
  - test/test_proc.rb
140
144
  - test/test_symbol.rb
141
145
  - test/test_variable.rb
@@ -167,7 +171,7 @@ rubyforge_project: ludy
167
171
  rubygems_version: 1.0.1
168
172
  signing_key:
169
173
  specification_version: 2
170
- summary: Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library.
174
+ summary: Aims to extend Ruby standard library, providing some useful tools that's not existed in the standard library, especially for functional programming.
171
175
  test_files:
172
176
  - test/test_all.rb
173
177
  - test/test_array.rb
@@ -176,6 +180,7 @@ test_files:
176
180
  - test/test_dices.rb
177
181
  - test/test_kernel.rb
178
182
  - test/test_lazy.rb
183
+ - test/test_paginator.rb
179
184
  - test/test_proc.rb
180
185
  - test/test_symbol.rb
181
186
  - test/test_variable.rb