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 +6 -0
- data/Manifest.txt +4 -0
- data/README +28 -5
- data/Rakefile +2 -2
- data/TODO +7 -0
- data/lib/ludy/helpers/check_box.rb +24 -0
- data/lib/ludy/kernel/public_send.rb +2 -2
- data/lib/ludy/list.rb +21 -0
- data/lib/ludy/paginator.rb +118 -0
- data/lib/ludy/symbol/to_proc.rb +2 -2
- data/spec/ludy_spec.rb +1 -1
- data/test/test_paginator.rb +60 -0
- metadata +9 -4
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
|
+
= 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
|
-
|
14
|
-
|
15
|
-
|
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.
|
23
|
+
PROJ.version = '0.1.2'
|
24
24
|
PROJ.exclude << '.DS_Store' << '^tmp'
|
25
25
|
PROJ.dependencies << 'rake'
|
26
26
|
|
data/TODO
CHANGED
@@ -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
|
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
|
data/lib/ludy/symbol/to_proc.rb
CHANGED
data/spec/ludy_spec.rb
CHANGED
@@ -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.
|
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-
|
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
|