liquor 0.1.1 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -9
- data/Gemfile +7 -0
- data/Guardfile +11 -0
- data/MIT-LICENSE +6 -2
- data/README.md +4 -122
- data/Rakefile +20 -23
- data/doc/language-spec.html +768 -0
- data/doc/language-spec.md +698 -0
- data/lib/liquor.rb +39 -68
- data/lib/liquor/ast_tools.rb +28 -0
- data/lib/liquor/compiler.rb +110 -0
- data/lib/liquor/context.rb +76 -254
- data/lib/liquor/diagnostics.rb +151 -0
- data/lib/liquor/drop/drop.rb +168 -0
- data/lib/liquor/drop/drop_delegation.rb +24 -0
- data/lib/liquor/drop/drop_scope.rb +118 -0
- data/lib/liquor/drop/dropable.rb +17 -0
- data/lib/liquor/emitter.rb +313 -0
- data/lib/liquor/extensions/kaminari.rb +14 -0
- data/lib/liquor/extensions/pagination.rb +235 -0
- data/lib/liquor/extensions/rails.rb +97 -0
- data/lib/liquor/extensions/thinking_sphinx.rb +14 -0
- data/lib/liquor/extensions/tire.rb +30 -0
- data/lib/liquor/external.rb +79 -0
- data/lib/liquor/function.rb +94 -0
- data/lib/liquor/grammar/lexer.rb +1223 -0
- data/lib/liquor/grammar/lexer.rl +297 -0
- data/lib/liquor/grammar/parser.racc +288 -0
- data/lib/liquor/grammar/parser.rb +885 -0
- data/lib/liquor/library.rb +41 -0
- data/lib/liquor/manager.rb +146 -0
- data/lib/liquor/runtime.rb +167 -0
- data/lib/liquor/stdlib/builtin_functions.rb +315 -0
- data/lib/liquor/stdlib/builtin_tags.rb +228 -0
- data/lib/liquor/stdlib/html_truncater.rb +162 -0
- data/lib/liquor/stdlib/partial_tags.rb +76 -0
- data/lib/liquor/tag.rb +83 -14
- data/lib/liquor/version.rb +1 -1
- data/liquor.gemspec +29 -6
- data/spec/builtins_spec.rb +264 -0
- data/spec/compiler_spec.rb +136 -0
- data/spec/context_spec.rb +49 -0
- data/spec/drop_delegation_spec.rb +21 -0
- data/spec/drop_spec.rb +222 -0
- data/spec/errors_spec.rb +40 -0
- data/spec/external_spec.rb +207 -0
- data/spec/function_spec.rb +80 -0
- data/spec/lexer_spec.rb +173 -0
- data/spec/library_spec.rb +18 -0
- data/spec/manager_spec.rb +84 -0
- data/spec/parser_spec.rb +381 -0
- data/spec/partials_spec.rb +74 -0
- data/spec/runtime_spec.rb +97 -0
- data/spec/spec_helper.rb +94 -0
- data/spec/tag_spec.rb +7 -0
- metadata +216 -173
- data/AUTHORS +0 -2
- data/CHANGELOG +0 -48
- data/Gemfile.lock +0 -91
- data/History.txt +0 -44
- data/LICENSE +0 -23
- data/example/server/example_servlet.rb +0 -37
- data/example/server/liquid_servlet.rb +0 -28
- data/example/server/liquor_servlet.rb +0 -28
- data/example/server/server.rb +0 -12
- data/example/server/templates/index.liquid +0 -6
- data/example/server/templates/index.liquor +0 -6
- data/example/server/templates/products.liquid +0 -45
- data/example/server/templates/products.liquor +0 -45
- data/init.rb +0 -8
- data/lib/extras/liquid_view.rb +0 -51
- data/lib/extras/liquor_view.rb +0 -51
- data/lib/liquor/block.rb +0 -101
- data/lib/liquor/condition.rb +0 -120
- data/lib/liquor/document.rb +0 -17
- data/lib/liquor/drop.rb +0 -256
- data/lib/liquor/errors.rb +0 -11
- data/lib/liquor/extensions.rb +0 -72
- data/lib/liquor/file_system.rb +0 -62
- data/lib/liquor/htmltags.rb +0 -74
- data/lib/liquor/module_ex.rb +0 -60
- data/lib/liquor/standardfilters.rb +0 -315
- data/lib/liquor/strainer.rb +0 -58
- data/lib/liquor/tags/assign.rb +0 -33
- data/lib/liquor/tags/capture.rb +0 -35
- data/lib/liquor/tags/case.rb +0 -83
- data/lib/liquor/tags/comment.rb +0 -9
- data/lib/liquor/tags/content_for.rb +0 -54
- data/lib/liquor/tags/cycle.rb +0 -59
- data/lib/liquor/tags/for.rb +0 -136
- data/lib/liquor/tags/if.rb +0 -80
- data/lib/liquor/tags/ifchanged.rb +0 -20
- data/lib/liquor/tags/include.rb +0 -56
- data/lib/liquor/tags/unless.rb +0 -33
- data/lib/liquor/tags/yield.rb +0 -49
- data/lib/liquor/template.rb +0 -181
- data/lib/liquor/variable.rb +0 -52
- data/performance/shopify.rb +0 -92
- data/performance/shopify/comment_form.rb +0 -33
- data/performance/shopify/database.rb +0 -45
- data/performance/shopify/json_filter.rb +0 -7
- data/performance/shopify/liquid.rb +0 -18
- data/performance/shopify/liquor.rb +0 -18
- data/performance/shopify/money_filter.rb +0 -18
- data/performance/shopify/paginate.rb +0 -93
- data/performance/shopify/shop_filter.rb +0 -98
- data/performance/shopify/tag_filter.rb +0 -25
- data/performance/shopify/vision.database.yml +0 -945
- data/performance/shopify/weight_filter.rb +0 -11
- data/performance/tests/dropify/article.liquid +0 -74
- data/performance/tests/dropify/blog.liquid +0 -33
- data/performance/tests/dropify/cart.liquid +0 -66
- data/performance/tests/dropify/collection.liquid +0 -22
- data/performance/tests/dropify/index.liquid +0 -47
- data/performance/tests/dropify/page.liquid +0 -8
- data/performance/tests/dropify/product.liquid +0 -68
- data/performance/tests/dropify/theme.liquid +0 -105
- data/performance/tests/ripen/article.liquid +0 -74
- data/performance/tests/ripen/blog.liquid +0 -13
- data/performance/tests/ripen/cart.liquid +0 -54
- data/performance/tests/ripen/collection.liquid +0 -29
- data/performance/tests/ripen/index.liquid +0 -32
- data/performance/tests/ripen/page.liquid +0 -4
- data/performance/tests/ripen/product.liquid +0 -75
- data/performance/tests/ripen/theme.liquid +0 -85
- data/performance/tests/tribble/404.liquid +0 -56
- data/performance/tests/tribble/article.liquid +0 -98
- data/performance/tests/tribble/blog.liquid +0 -41
- data/performance/tests/tribble/cart.liquid +0 -134
- data/performance/tests/tribble/collection.liquid +0 -70
- data/performance/tests/tribble/index.liquid +0 -94
- data/performance/tests/tribble/page.liquid +0 -56
- data/performance/tests/tribble/product.liquid +0 -116
- data/performance/tests/tribble/search.liquid +0 -51
- data/performance/tests/tribble/theme.liquid +0 -90
- data/performance/tests/vogue/article.liquid +0 -66
- data/performance/tests/vogue/blog.liquid +0 -32
- data/performance/tests/vogue/cart.liquid +0 -58
- data/performance/tests/vogue/collection.liquid +0 -19
- data/performance/tests/vogue/index.liquid +0 -22
- data/performance/tests/vogue/page.liquid +0 -3
- data/performance/tests/vogue/product.liquid +0 -62
- data/performance/tests/vogue/theme.liquid +0 -122
- data/test/assign_test.rb +0 -11
- data/test/block_test.rb +0 -58
- data/test/capture_test.rb +0 -41
- data/test/condition_test.rb +0 -115
- data/test/content_for_test.rb +0 -15
- data/test/context_test.rb +0 -479
- data/test/drop_test.rb +0 -162
- data/test/error_handling_test.rb +0 -89
- data/test/extra/breakpoint.rb +0 -547
- data/test/extra/caller.rb +0 -80
- data/test/file_system_test.rb +0 -30
- data/test/filter_test.rb +0 -147
- data/test/helper.rb +0 -24
- data/test/html_tag_test.rb +0 -31
- data/test/if_else_test.rb +0 -139
- data/test/include_tag_test.rb +0 -129
- data/test/module_ex_test.rb +0 -89
- data/test/output_test.rb +0 -121
- data/test/parsing_quirks_test.rb +0 -54
- data/test/regexp_test.rb +0 -45
- data/test/security_test.rb +0 -41
- data/test/standard_filter_test.rb +0 -170
- data/test/standard_tag_test.rb +0 -405
- data/test/statements_test.rb +0 -137
- data/test/strainer_test.rb +0 -27
- data/test/template_test.rb +0 -82
- data/test/test_helper.rb +0 -28
- data/test/unless_else_test.rb +0 -27
- data/test/variable_test.rb +0 -173
- data/test/yield_test.rb +0 -24
@@ -0,0 +1,151 @@
|
|
1
|
+
module Liquor
|
2
|
+
class Diagnostic < StandardError
|
3
|
+
attr_reader :location
|
4
|
+
attr_reader :raw_message
|
5
|
+
|
6
|
+
def initialize(message, location=nil)
|
7
|
+
location_info = ""
|
8
|
+
if location
|
9
|
+
if location.include? :file
|
10
|
+
location_info << "`#{location[:file]}'"
|
11
|
+
end
|
12
|
+
|
13
|
+
if location.include? :line
|
14
|
+
location_info << ": line #{location[:line] + 1}"
|
15
|
+
if location.include? :start
|
16
|
+
location_info << ", column #{location[:start] + 1}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@location = location
|
22
|
+
@raw_message = message
|
23
|
+
|
24
|
+
if location_info.empty?
|
25
|
+
super(message)
|
26
|
+
else
|
27
|
+
super("#{message} at #{location_info}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def error?
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
def decorate(source)
|
36
|
+
if @location && @location.has_key?(:line)
|
37
|
+
line = source.lines.drop(@location[:line]).first
|
38
|
+
line ||= "(source spans only #{source.lines.count} lines)"
|
39
|
+
line = line.rstrip
|
40
|
+
|
41
|
+
if @location.has_key? :start
|
42
|
+
start_col = tabify_column line, @location[:start]
|
43
|
+
pointer = " " * start_col
|
44
|
+
|
45
|
+
if location.has_key? :end
|
46
|
+
end_col = tabify_column line, @location[:end]
|
47
|
+
|
48
|
+
pointer += "^" * (end_col - start_col + 1)
|
49
|
+
else
|
50
|
+
pointer += "^"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
[ line, pointer ].compact
|
56
|
+
end
|
57
|
+
|
58
|
+
# Dammit, why should I replicate parts of VT-52 all over again?!
|
59
|
+
# Curse backwards compatibility and C.
|
60
|
+
def tabify_column(line, column)
|
61
|
+
display_column = 0
|
62
|
+
|
63
|
+
line[0...column].each_char do |char|
|
64
|
+
if char == "\t"
|
65
|
+
display_column += 8 - (display_column % 8)
|
66
|
+
else
|
67
|
+
display_column += 1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
display_column
|
72
|
+
end
|
73
|
+
|
74
|
+
def as_json(options = nil)
|
75
|
+
{
|
76
|
+
message: @raw_message,
|
77
|
+
is_error: error?,
|
78
|
+
location: @location,
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_json(options = nil)
|
83
|
+
as_json.to_json(options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Error < Diagnostic
|
88
|
+
def error?
|
89
|
+
true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class SyntaxError < Error
|
94
|
+
end
|
95
|
+
|
96
|
+
class PartialError < Error
|
97
|
+
end
|
98
|
+
|
99
|
+
class ArgumentError < Error
|
100
|
+
end
|
101
|
+
|
102
|
+
class NameError < Error
|
103
|
+
end
|
104
|
+
|
105
|
+
class TypeError < Error
|
106
|
+
end
|
107
|
+
|
108
|
+
class ArgumentTypeError < Error
|
109
|
+
attr_reader :location
|
110
|
+
|
111
|
+
def initialize(message, location=nil)
|
112
|
+
location_info = ""
|
113
|
+
if location
|
114
|
+
if location.include? :function
|
115
|
+
location_info << "function `#{location[:function]}'"
|
116
|
+
if location.include? :argument
|
117
|
+
if location[:argument].nil?
|
118
|
+
location_info << ", unnamed argument"
|
119
|
+
else
|
120
|
+
location_info << ", argument `#{location[:argument]}'"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
if location_info.empty?
|
127
|
+
super(message, location)
|
128
|
+
else
|
129
|
+
super("#{message} at #{location_info}", location)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class HostError < Error
|
135
|
+
attr_reader :original_error, :host_backtrace
|
136
|
+
|
137
|
+
def initialize(message, original_error, host_backtrace, location=nil)
|
138
|
+
@original_error = original_error
|
139
|
+
@host_backtrace = host_backtrace
|
140
|
+
|
141
|
+
if message.nil?
|
142
|
+
message = "#{original_error.class}: #{original_error.message}"
|
143
|
+
end
|
144
|
+
|
145
|
+
super(message, location)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class Deprecation < Diagnostic
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Liquor
|
4
|
+
class Drop
|
5
|
+
include Liquor::External
|
6
|
+
|
7
|
+
attr_reader :source
|
8
|
+
|
9
|
+
def self.inherited(klass)
|
10
|
+
klass.instance_exec do
|
11
|
+
const_set :Scope, Class.new(::Liquor::Drop::Scope)
|
12
|
+
const_get(:Scope).instance_exec do
|
13
|
+
export # refresh liquor_exports
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(source)
|
19
|
+
@source = source
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.attributes(*attrs)
|
23
|
+
attrs.each do |attr|
|
24
|
+
define_method(attr) {
|
25
|
+
@source.send(attr)
|
26
|
+
}
|
27
|
+
export attr
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.scopes(*scopes)
|
32
|
+
const_get(:Scope).instance_exec do
|
33
|
+
scopes.each do |scope|
|
34
|
+
define_method(scope) { |*args|
|
35
|
+
args = Drop.unwrap_scope_arguments(args)
|
36
|
+
DropDelegation.wrap_scope @source.send(scope, *args)
|
37
|
+
}
|
38
|
+
export scope
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.unwrap_scope_arguments(args)
|
44
|
+
args.map do |arg|
|
45
|
+
case arg
|
46
|
+
when Drop
|
47
|
+
arg.id
|
48
|
+
when Drop::Scope
|
49
|
+
unwrap_scope_arguments(arg.to_a)
|
50
|
+
when Array
|
51
|
+
unwrap_scope_arguments(arg)
|
52
|
+
when Hash
|
53
|
+
Hash[arg.keys.zip(unwrap_scope_arguments(arg.values))]
|
54
|
+
else
|
55
|
+
arg
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.define_singular_association_accessor(name, options={})
|
61
|
+
if options.has_key?(:if) && options.has_key?(:unless)
|
62
|
+
raise ArgumentError, "It is pointless to pass both :if and :unless conditions to has_one or belongs_to"
|
63
|
+
end
|
64
|
+
|
65
|
+
unsupported_options = (options.keys - [:if, :unless])
|
66
|
+
if unsupported_options.any?
|
67
|
+
raise ArgumentError, "Unsupported options #{unsupported_options.join(", ")}"
|
68
|
+
end
|
69
|
+
|
70
|
+
define_method(name) {
|
71
|
+
value = @source.send(name)
|
72
|
+
|
73
|
+
if self.class.check_singular_condition(value, options)
|
74
|
+
if value.nil?
|
75
|
+
nil
|
76
|
+
else
|
77
|
+
DropDelegation.wrap_element(value)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
}
|
81
|
+
|
82
|
+
export name
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.check_singular_condition(object, options)
|
86
|
+
execute = lambda do |object, condition|
|
87
|
+
if condition.is_a? Symbol
|
88
|
+
object.send(condition)
|
89
|
+
elsif condition.respond_to? :call
|
90
|
+
condition.(object)
|
91
|
+
else
|
92
|
+
raise ArgumentError, "Invalid condition type #{condition.class}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
if options[:if]
|
97
|
+
execute.(object, options[:if])
|
98
|
+
elsif options[:unless]
|
99
|
+
!execute.(object, options[:unless])
|
100
|
+
else
|
101
|
+
true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.belongs_to(name, options={})
|
106
|
+
define_singular_association_accessor(name, options)
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.has_one(name, options={})
|
110
|
+
define_singular_association_accessor(name, options)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.has_many(name, options={})
|
114
|
+
unsupported_options = (options.keys - [:scope, :include])
|
115
|
+
if unsupported_options.any?
|
116
|
+
raise ArgumentError, "Unsupported options #{unsupported_options.join(", ")}"
|
117
|
+
end
|
118
|
+
|
119
|
+
define_method(name) {
|
120
|
+
value = @source.send(name)
|
121
|
+
|
122
|
+
if options[:scope]
|
123
|
+
# Sequentally apply each symbol from options[:scope]
|
124
|
+
# to the current scope, starting from `value' and using
|
125
|
+
# each result as current scope for the next operation.
|
126
|
+
value = Array(options[:scope]).reduce(value, &:send)
|
127
|
+
end
|
128
|
+
|
129
|
+
if options[:include]
|
130
|
+
Array(options[:include]).each do |collection|
|
131
|
+
value = value.includes(collection)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
DropDelegation.wrap_scope(value, value.klass)
|
136
|
+
}
|
137
|
+
|
138
|
+
export name
|
139
|
+
end
|
140
|
+
|
141
|
+
def entity
|
142
|
+
@source.class.model_name.to_s
|
143
|
+
end
|
144
|
+
export :entity
|
145
|
+
|
146
|
+
def ==(other)
|
147
|
+
if other.is_a? Liquor::Drop
|
148
|
+
self.source == other.source
|
149
|
+
else
|
150
|
+
other == self
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
alias eql? ==
|
155
|
+
|
156
|
+
def hash
|
157
|
+
@source.hash
|
158
|
+
end
|
159
|
+
|
160
|
+
def to_drop
|
161
|
+
self
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
require_relative 'drop_delegation'
|
167
|
+
require_relative 'drop_scope'
|
168
|
+
require_relative 'dropable'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Liquor
|
2
|
+
module DropDelegation
|
3
|
+
# aka module_method for every method.
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def wrap_scope(scope, klass=scope)
|
7
|
+
drop_klass = "#{klass.name}Drop::Scope".constantize
|
8
|
+
drop_klass.new(scope)
|
9
|
+
end
|
10
|
+
|
11
|
+
def wrap_element(element)
|
12
|
+
unless element.nil?
|
13
|
+
drop_klass = "#{element.class.name}Drop".constantize
|
14
|
+
drop_klass.new(element)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def unwrap_drop_class(klass)
|
19
|
+
drop_klass_name = klass.name
|
20
|
+
model_class_name = drop_klass_name.sub(/Drop$/, '')
|
21
|
+
model_class_name.constantize
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Liquor
|
2
|
+
class Drop::Scope
|
3
|
+
include Liquor::External
|
4
|
+
|
5
|
+
attr_reader :source
|
6
|
+
|
7
|
+
def initialize(source)
|
8
|
+
unless source.respond_to? :each
|
9
|
+
source = source.all
|
10
|
+
end
|
11
|
+
|
12
|
+
@source = source
|
13
|
+
end
|
14
|
+
|
15
|
+
# Not exported.
|
16
|
+
def to_a
|
17
|
+
@source.map do |elem|
|
18
|
+
DropDelegation.wrap_element(elem)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias to_ary to_a
|
22
|
+
|
23
|
+
def entity
|
24
|
+
@source.model_name.to_s
|
25
|
+
end
|
26
|
+
export :entity
|
27
|
+
|
28
|
+
def find_by(_, fields={})
|
29
|
+
fields, = Drop.unwrap_scope_arguments([ fields ])
|
30
|
+
|
31
|
+
result = @source.where(fields).first
|
32
|
+
DropDelegation.wrap_element result if result
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_all_by(_, fields={})
|
36
|
+
fields, = Drop.unwrap_scope_arguments([ fields ])
|
37
|
+
|
38
|
+
result = @source.where(fields)
|
39
|
+
DropDelegation.wrap_scope(result)
|
40
|
+
end
|
41
|
+
|
42
|
+
export :find_all_by, :find_by
|
43
|
+
|
44
|
+
def except(record)
|
45
|
+
record, = Drop.unwrap_scope_arguments([ record ])
|
46
|
+
|
47
|
+
result = @source.where(@source.arel_table[:id].eq(record).not)
|
48
|
+
DropDelegation.wrap_scope(result)
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_except_by(_, fields={})
|
52
|
+
fields, = Drop.unwrap_scope_arguments([ fields ])
|
53
|
+
|
54
|
+
result = @source.
|
55
|
+
where(fields.map do |key, value|
|
56
|
+
@source.arel_table[key].eq(value)
|
57
|
+
end.reduce(&:and).not)
|
58
|
+
DropDelegation.wrap_scope(result)
|
59
|
+
end
|
60
|
+
|
61
|
+
export :except, :find_except_by
|
62
|
+
|
63
|
+
def first
|
64
|
+
DropDelegation.wrap_element @source.first
|
65
|
+
end
|
66
|
+
|
67
|
+
def last
|
68
|
+
DropDelegation.wrap_element @source.last
|
69
|
+
end
|
70
|
+
|
71
|
+
def [](index)
|
72
|
+
DropDelegation.wrap_element @source[index]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Not exported. No block support in Liquor.
|
76
|
+
def each
|
77
|
+
@source.each do |elem|
|
78
|
+
yield DropDelegation.wrap_element(elem)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Not exported. No ? in names in Liquor.
|
83
|
+
def include?(elem)
|
84
|
+
if elem.is_a? Liquor::Drop
|
85
|
+
@source.include? elem.source
|
86
|
+
else
|
87
|
+
false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def pluck(attribute)
|
92
|
+
@source.map do |elem|
|
93
|
+
DropDelegation.wrap_element(elem).liquor_send(attribute.to_s, [])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def count
|
98
|
+
@source.count
|
99
|
+
end
|
100
|
+
alias size count # for builtin compatibility
|
101
|
+
|
102
|
+
export :first, :last, :[], :pluck
|
103
|
+
|
104
|
+
def limit(count)
|
105
|
+
DropDelegation.wrap_scope @source.limit(count)
|
106
|
+
end
|
107
|
+
|
108
|
+
def offset(count)
|
109
|
+
DropDelegation.wrap_scope @source.offset(count)
|
110
|
+
end
|
111
|
+
|
112
|
+
def reverse
|
113
|
+
DropDelegation.wrap_scope @source.reverse_order
|
114
|
+
end
|
115
|
+
|
116
|
+
export :limit, :offset, :reverse
|
117
|
+
end
|
118
|
+
end
|