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 +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
|