ludy 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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