ruby_motion_query 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +21 -0
  3. data/README.md +964 -0
  4. data/lib/ruby_motion_query.rb +8 -0
  5. data/motion/ext.rb +34 -0
  6. data/motion/ruby_motion_query/actions.rb +44 -0
  7. data/motion/ruby_motion_query/animations.rb +125 -0
  8. data/motion/ruby_motion_query/app.rb +71 -0
  9. data/motion/ruby_motion_query/base.rb +161 -0
  10. data/motion/ruby_motion_query/color.rb +80 -0
  11. data/motion/ruby_motion_query/data.rb +32 -0
  12. data/motion/ruby_motion_query/device.rb +73 -0
  13. data/motion/ruby_motion_query/enumerablish.rb +74 -0
  14. data/motion/ruby_motion_query/event.rb +125 -0
  15. data/motion/ruby_motion_query/events.rb +65 -0
  16. data/motion/ruby_motion_query/factory.rb +32 -0
  17. data/motion/ruby_motion_query/font.rb +66 -0
  18. data/motion/ruby_motion_query/format.rb +54 -0
  19. data/motion/ruby_motion_query/image.rb +79 -0
  20. data/motion/ruby_motion_query/position.rb +45 -0
  21. data/motion/ruby_motion_query/selectors.rb +56 -0
  22. data/motion/ruby_motion_query/stylers/ui_button_styler.rb +32 -0
  23. data/motion/ruby_motion_query/stylers/ui_control_styler.rb +8 -0
  24. data/motion/ruby_motion_query/stylers/ui_date_picker_styler.rb +8 -0
  25. data/motion/ruby_motion_query/stylers/ui_image_view_styler.rb +14 -0
  26. data/motion/ruby_motion_query/stylers/ui_label_styler.rb +36 -0
  27. data/motion/ruby_motion_query/stylers/ui_navigation_bar_styler.rb +8 -0
  28. data/motion/ruby_motion_query/stylers/ui_page_control_styler.rb +8 -0
  29. data/motion/ruby_motion_query/stylers/ui_refresh_control_styler.rb +8 -0
  30. data/motion/ruby_motion_query/stylers/ui_scroll_view_styler.rb +10 -0
  31. data/motion/ruby_motion_query/stylers/ui_segmented_control_styler.rb +8 -0
  32. data/motion/ruby_motion_query/stylers/ui_slider_styler.rb +8 -0
  33. data/motion/ruby_motion_query/stylers/ui_stepper_styler.rb +8 -0
  34. data/motion/ruby_motion_query/stylers/ui_switch_styler.rb +10 -0
  35. data/motion/ruby_motion_query/stylers/ui_tab_bar_styler.rb +8 -0
  36. data/motion/ruby_motion_query/stylers/ui_table_view_cell_styler.rb +8 -0
  37. data/motion/ruby_motion_query/stylers/ui_table_view_styler.rb +8 -0
  38. data/motion/ruby_motion_query/stylers/ui_text_field_styler.rb +8 -0
  39. data/motion/ruby_motion_query/stylers/ui_text_view_styler.rb +8 -0
  40. data/motion/ruby_motion_query/stylers/ui_view_styler.rb +243 -0
  41. data/motion/ruby_motion_query/stylesheet.rb +185 -0
  42. data/motion/ruby_motion_query/subviews.rb +52 -0
  43. data/motion/ruby_motion_query/tags.rb +14 -0
  44. data/motion/ruby_motion_query/traverse.rb +183 -0
  45. data/motion/ruby_motion_query/utils.rb +53 -0
  46. metadata +89 -0
@@ -0,0 +1,8 @@
1
+ unless defined?(Motion::Project::App)
2
+ raise "This must be required from within a RubyMotion Rakefile"
3
+ end
4
+
5
+ Motion::Project::App.setup do |app|
6
+ parent = File.join(File.dirname(__FILE__), '..')
7
+ app.files.unshift(Dir.glob(File.join(parent, "motion/**/*.rb")))
8
+ end
data/motion/ext.rb ADDED
@@ -0,0 +1,34 @@
1
+ class UIView
2
+ def rmq_data
3
+ @_rmq_data ||= RubyMotionQuery::ViewData.new
4
+ end
5
+
6
+ protected
7
+
8
+ def rmq(*selectors)
9
+ RubyMotionQuery::RMQ.create_with_selectors(selectors, RubyMotionQuery::RMQ.controller_for_view(self))
10
+ end
11
+ end
12
+
13
+ class UIViewController
14
+ def rmq(*selectors)
15
+ if RubyMotionQuery::RMQ.cache_controller_rmqs && selectors.length == 0
16
+ rmq_data.rmq ||= RubyMotionQuery::RMQ.create_with_selectors(selectors, self)
17
+ else
18
+ RubyMotionQuery::RMQ.create_with_selectors(selectors, self)
19
+ end
20
+ end
21
+
22
+ def rmq_data
23
+ @_rmq_data ||= RubyMotionQuery::ControllerData.new
24
+ end
25
+ end
26
+
27
+ # Used in console, so that you can just call rmq with an view or controller as self
28
+ class TopLevel
29
+ def rmq(*selectors)
30
+ if window = RubyMotionQuery::RMQ.app.window
31
+ RubyMotionQuery::RMQ.create_with_selectors(selectors, window.subviews.first)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ def attr(new_settings)
4
+ selected.each do |view|
5
+ new_settings.each do |k,v|
6
+ view.send "#{k}=", v
7
+ end
8
+ end
9
+ self
10
+ end
11
+
12
+ def send(method, args = nil)
13
+ selected.each do |view|
14
+ if args
15
+ view.__send__ method, args
16
+ else
17
+ view.__send__ method
18
+ end
19
+ end
20
+ self
21
+ end
22
+
23
+ def hide
24
+ selected.each { |view| view.hidden = true }
25
+ self
26
+ end
27
+
28
+ def show
29
+ selected.each { |view| view.hidden = false }
30
+ self
31
+ end
32
+
33
+ def toggle
34
+ selected.each { |view| view.hidden = !view.hidden? }
35
+ self
36
+ end
37
+
38
+ def toggle_enabled
39
+ selected.each { |view| view.enabled = !view.enabled? }
40
+ self
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,125 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ def animate(opts = {})
4
+ working_selected = self.selected
5
+ @_rmq = self # @ for rm bug
6
+
7
+ animations_lambda = if (animations_callback = (opts.delete(:animations) || opts.delete(:changes)))
8
+ -> do
9
+ working_selected.each do |view|
10
+ animations_callback.call(@_rmq.create_rmq_in_context(view))
11
+ end
12
+ end
13
+ else
14
+ nil
15
+ end
16
+
17
+ return self unless animations_lambda
18
+
19
+ after_lambda = if (after_callback = (opts.delete(:completion) || opts.delete(:after)))
20
+ -> (did_finish) {
21
+ after_callback.call(did_finish, @_rmq)
22
+ }
23
+ else
24
+ nil
25
+ end
26
+
27
+ UIView.animateWithDuration(
28
+ opts.delete(:duration) || 0.3,
29
+ delay: opts.delete(:delay) || 0,
30
+ options: (opts.delete(:options) || UIViewAnimationOptionCurveEaseInOut),
31
+ animations: animations_lambda,
32
+ completion: after_lambda
33
+ )
34
+
35
+ self
36
+ end
37
+
38
+ def animations
39
+ @_animations ||= Animations.new(self)
40
+ end
41
+ end
42
+
43
+ class Animations
44
+ def initialize(rmq)
45
+ @rmq = rmq
46
+ end
47
+
48
+ def fade_in(opts = {})
49
+ @rmq.each do |view|
50
+ view.layer.opacity = 0.0
51
+ view.hidden = false
52
+ end
53
+
54
+ opts[:animations] = lambda do |rmq|
55
+ rmq.get.layer.opacity = 1.0
56
+ end
57
+
58
+ @rmq.animate(opts)
59
+ end
60
+
61
+ def fade_out(opts = {})
62
+ opts[:animations] = lambda do |rmq|
63
+ rmq.get.layer.opacity = 0.0
64
+ end
65
+
66
+ @completion_block = opts[:completion] || opts[:after]
67
+
68
+ opts[:completion] = lambda do |did_finish, rmq|
69
+ rmq.each do |view|
70
+ view.hidden = true
71
+ view.layer.opacity = 1.0
72
+ end
73
+
74
+ @completion_block.call(did_finish, rmq) if @completion_block
75
+ end
76
+
77
+ @rmq.animate(opts)
78
+ end
79
+
80
+ def throb
81
+ @rmq.animate(
82
+ duration: 0.1,
83
+ animations: -> (q) {
84
+ q.style {|st| st.scale = 1.1}
85
+ },
86
+ completion: -> (did_finish, q) {
87
+ q.animate(
88
+ duration: 0.4,
89
+ animations: -> (cq) {
90
+ cq.style {|st| st.scale = 1.0}
91
+ }
92
+ )
93
+ }
94
+ )
95
+ end
96
+
97
+ def blink
98
+ self.fade_out(duration: 0.2, after: lambda {|did_finish, rmq| rmq.animations.fade_in(duration: 0.2)})
99
+ end
100
+
101
+ def start_spinner(style = UIActivityIndicatorViewStyleGray)
102
+ spinner = Animations.window_spinner(style)
103
+ spinner.startAnimating
104
+ @rmq.create_rmq_in_context(spinner)
105
+ end
106
+
107
+ def stop_spinner
108
+ spinner = Animations.window_spinner
109
+ spinner.stopAnimating
110
+ @rmq.create_rmq_in_context(spinner)
111
+ end
112
+
113
+ def self.window_spinner(style = UIActivityIndicatorViewStyleGray)
114
+ @_window_spinner ||= begin
115
+ window = RMQ.app.window
116
+ UIActivityIndicatorView.alloc.initWithActivityIndicatorStyle(style).tap do |o|
117
+ o.center = window.center
118
+ o.hidesWhenStopped = true
119
+ o.layer.zPosition = NSIntegerMax
120
+ window.addSubview(o)
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,71 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ def app
4
+ App
5
+ end
6
+
7
+ def self.app
8
+ App
9
+ end
10
+
11
+ # TODO This is a bit wierd and may not work, need to think on this
12
+ # It's also confusing use of rmq which assumes a controller and subviews
13
+ #def window_rmq
14
+ #RMQ.create_with_selectors([App.window], self.context)
15
+ #end
16
+
17
+ #def self.window_rmq
18
+ #RMQ.create_with_selectors([App.window], App.window)
19
+ #end
20
+ end
21
+
22
+ class App
23
+ class << self
24
+
25
+ def window
26
+ UIApplication.sharedApplication.keyWindow || UIApplication.sharedApplication.windows[0]
27
+ end
28
+
29
+ def delegate
30
+ UIApplication.sharedApplication.delegate
31
+ end
32
+
33
+ def environment
34
+ RUBYMOTION_ENV.to_sym
35
+ end
36
+
37
+ def release?
38
+ environment == :release
39
+ end
40
+ alias :production? :release?
41
+
42
+ def test?
43
+ environment == :test
44
+ end
45
+
46
+ def development?
47
+ environment == :development
48
+ end
49
+
50
+ def version
51
+ NSBundle.mainBundle.infoDictionary['CFBundleVersion']
52
+ end
53
+
54
+ def name
55
+ NSBundle.mainBundle.objectForInfoDictionaryKey 'CFBundleDisplayName'
56
+ end
57
+
58
+ def identifier
59
+ NSBundle.mainBundle.bundleIdentifier
60
+ end
61
+
62
+ def resource_path
63
+ NSBundle.mainBundle.resourcePath
64
+ end
65
+
66
+ def document_path
67
+ NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,161 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ attr_accessor :context, :parent_rmq
4
+
5
+ def initialize
6
+ @selected_dirty = true
7
+ end
8
+
9
+ def selected=(value)
10
+ @_selected = value
11
+ @selected_dirty = false
12
+ end
13
+ def selected
14
+ if @selected_dirty
15
+ @_selected = []
16
+
17
+ if RMQ.is_blank?(self.selectors)
18
+ @_selected << context_or_context_view
19
+ else
20
+ working_selectors = self.selectors.dup
21
+ extract_views_from_selectors(@_selected, working_selectors)
22
+
23
+ unless RMQ.is_blank?(working_selectors)
24
+ subviews = all_subviews_for(root_view)
25
+ subviews.each do |subview|
26
+ @_selected << subview if match(subview, working_selectors)
27
+ end
28
+ end
29
+
30
+ @_selected.uniq!
31
+ end
32
+
33
+ @selected_dirty = false
34
+ else
35
+ @_selected ||= []
36
+ end
37
+
38
+ @_selected
39
+ end
40
+
41
+ # The view(s) this rmq was derived from
42
+ def origin_views
43
+ if @parent_rmq
44
+ @parent_rmq.selected
45
+ else
46
+ [self.view_controller.view]
47
+ end
48
+ end
49
+
50
+ # Returns a view or array of views.
51
+ # Normally used to get the only view in selected.
52
+ #
53
+ # @example
54
+ # rmq(foo).parent.get.some_method_on_parent
55
+ def get
56
+ sel = self.selected
57
+ if sel.length == 1
58
+ sel.first
59
+ else
60
+ sel
61
+ end
62
+ end
63
+
64
+ def root?
65
+ (selected.length == 1) && (selected.first == @context)
66
+ end
67
+
68
+ def context_or_context_view
69
+ if @context.is_a?(UIViewController)
70
+ @context.view
71
+ else
72
+ @context
73
+ end
74
+ end
75
+
76
+ def extract_views_from_selectors(view_container, working_selectors)
77
+ unless RMQ.is_blank?(working_selectors)
78
+ working_selectors.each do |selector|
79
+ if selector.is_a?(UIView)
80
+ view_container << working_selectors.delete(selector)
81
+ end
82
+ end
83
+ end
84
+ [view_container, working_selectors]
85
+ end
86
+
87
+ def all_subviews_for(view)
88
+ # TODO maybe cache this, and invalidate cache properly
89
+ out = []
90
+ if view.subviews
91
+ view.subviews.each do |subview|
92
+ out << subview
93
+ out << all_subviews_for(subview)
94
+ end
95
+ out.flatten!
96
+ end
97
+
98
+ out
99
+ end
100
+
101
+ def all_superviews_for(view, out = [])
102
+ if (nr = view.nextResponder) && nr.is_a?(UIView)
103
+ out << nr
104
+ all_superviews_for(nr, out)
105
+ end
106
+ out
107
+ end
108
+
109
+ def inspect
110
+ out = "RMQ #{self.object_id}. #{self.count} selected. selectors: #{self.selectors.to_s}. .log for more info"
111
+ out << "\n[#{selected.first}]" if self.count == 1
112
+ out
113
+ end
114
+
115
+ def log(opt = nil)
116
+ wide = (opt == :wide)
117
+ out = "\n object_id | class | style_name | frame |"
118
+ out << "\n" unless wide
119
+ out << " sv id | superview | subviews count | tags |"
120
+ line = " - - - - - - | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - |\n"
121
+ out << "\n"
122
+ out << line.chop if wide
123
+ out << line
124
+
125
+ selected.each do |view|
126
+ out << " #{view.object_id.to_s.ljust(12)}|"
127
+ out << " #{view.class.name[0..21].ljust(22)}|"
128
+ out << " #{(view.rmq_data.style_name || '')[0..23].ljust(24)}|"
129
+
130
+ s = ""
131
+ if view.origin
132
+ format = '#0.#'
133
+ s = " {l: #{RMQ.format.numeric(view.origin.x, format)}"
134
+ s << ", t: #{RMQ.format.numeric(view.origin.y, format)}"
135
+ s << ", w: #{RMQ.format.numeric(view.size.width, format)}"
136
+ s << ", h: #{RMQ.format.numeric(view.size.height, format)}}"
137
+ end
138
+ out << s.ljust(33)
139
+ out << '|'
140
+
141
+ out << "\n" unless wide
142
+ out << " #{view.superview.object_id.to_s.ljust(12)}|"
143
+ out << " #{(view.superview ? view.superview.class.name : '')[0..21].ljust(22)}|"
144
+ out << " #{view.subviews.length.to_s.ljust(23)} |"
145
+ #out << " #{view.subviews.length.to_s.rjust(8)} #{view.superview.class.name.ljust(20)} #{view.superview.object_id.to_s.rjust(10)}"
146
+ out << " #{view.rmq_data.tag_names.join(',').ljust(32)}|"
147
+ out << "\n"
148
+ out << line unless wide
149
+ end
150
+
151
+ out << "RMQ #{self.object_id}. #{self.count} selected. selectors: #{self.selectors.to_s}"
152
+
153
+ puts out
154
+ end
155
+
156
+ class << self
157
+ attr_accessor :cache_controller_rmqs
158
+ @cache_controller_rmqs = true
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,80 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ def self.color
4
+ Color
5
+ end
6
+
7
+ def color
8
+ Color
9
+ end
10
+ end
11
+
12
+ class Color < UIColor
13
+
14
+ class << self
15
+ alias :clear :clearColor
16
+ alias :white :whiteColor
17
+ alias :light_gray :lightGrayColor
18
+ alias :gray :grayColor
19
+ alias :dark_gray :darkGrayColor
20
+ alias :black :blackColor
21
+
22
+ alias :red :redColor
23
+ alias :green :greenColor
24
+ alias :blue :blueColor
25
+ alias :yellow :yellowColor
26
+ alias :orange :orangeColor
27
+ alias :purple :purpleColor
28
+ alias :brown :brownColor
29
+ alias :cyan :cyanColor
30
+ alias :magenta :magentaColor
31
+
32
+ alias :table_view :groupTableViewBackgroundColor
33
+ alias :scroll_view :scrollViewTexturedBackgroundColor
34
+ alias :flipside :viewFlipsideBackgroundColor
35
+ alias :under_page :underPageBackgroundColor
36
+ alias :light_text :lightTextColor
37
+ alias :dark_text :darkTextColor
38
+
39
+ def add_named(key, hex_or_color)
40
+ color = if hex_or_color.is_a?(String)
41
+ Color.from_hex(hex_or_color)
42
+ else
43
+ hex_or_color
44
+ end
45
+
46
+ Color.define_singleton_method(key) do
47
+ color
48
+ end
49
+ end
50
+
51
+ # Thanks bubblewrap for this method
52
+ def from_hex(hex_color)
53
+ hex_color.gsub!("#", "")
54
+ case hex_color.size
55
+ when 3
56
+ colors = hex_color.scan(%r{[0-9A-Fa-f]}).map{ |el| (el * 2).to_i(16) }
57
+ when 6
58
+ colors = hex_color.scan(%r<[0-9A-Fa-f]{2}>).map{ |el| el.to_i(16) }
59
+ else
60
+ raise ArgumentError
61
+ end
62
+ if colors.size == 3
63
+ from_rgba(colors[0], colors[1], colors[2], 1.0)
64
+ else
65
+ raise ArgumentError
66
+ end
67
+ end
68
+
69
+ def from_rgba(r,g,b,a)
70
+ UIColor.colorWithRed((r/255.0), green: (g/255.0), blue: (b/255.0), alpha: a)
71
+ end
72
+
73
+ def from_hsva(h,s,v,a)
74
+ UIColor.alloc.initWithHue(h, saturation: s, brightness: v, alpha: a)
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,32 @@
1
+ module RubyMotionQuery
2
+ class ViewData
3
+ attr_accessor :events, :style_name
4
+
5
+ def tags
6
+ @_tags ||= {}
7
+ end
8
+
9
+ def tag_names
10
+ tags.keys
11
+ end
12
+
13
+ def tag(*tag_or_tags)
14
+ tag_or_tags.flatten!
15
+ tag_or_tags.each do |tag_name|
16
+ tags[tag_name] = 1
17
+ end
18
+ end
19
+
20
+ def has_tag?(tag_name = nil)
21
+ if tag_name
22
+ tags.include?(tag_name)
23
+ else
24
+ RMQ.is_blank?(@_tags)
25
+ end
26
+ end
27
+ end
28
+
29
+ class ControllerData
30
+ attr_accessor :stylesheet, :rmq
31
+ end
32
+ end
@@ -0,0 +1,73 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ def device
4
+ Device
5
+ end
6
+ def self.device
7
+ Device
8
+ end
9
+ end
10
+
11
+ class Device
12
+ class << self
13
+ def screen
14
+ UIScreen.mainScreen
15
+ end
16
+
17
+ def width
18
+ @_width ||= Device.screen.bounds.size.width
19
+ end
20
+
21
+ def height
22
+ @_height ||= Device.screen.bounds.size.height
23
+ end
24
+
25
+ def ipad?
26
+ @_ipad = (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) if @_ipad.nil?
27
+ @_ipad
28
+ end
29
+
30
+ def iphone?
31
+ @_iphone = (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone) if @_iphone.nil?
32
+ @_iphone
33
+ end
34
+
35
+ def four_inch?
36
+ @_four_inch = (Device.height == 568.0) if @_four_inch.nil?
37
+ @_four_inch
38
+ end
39
+
40
+ def retina?()
41
+ if @_retina.nil?
42
+ main_screen = Device.screen
43
+ @_retina = !!(main_screen.respondsToSelector('displayLinkWithTarget:selector:') && main_screen.scale == 2.0)
44
+ end
45
+
46
+ @_retina
47
+ end
48
+
49
+ def orientation
50
+ ORIENTATIONS[UIDevice.currentDevice.orientation] || :unknown
51
+ end
52
+
53
+ def landscape?
54
+ Device.orientation == :landscape_Left || Device.orientation == :landscape_right
55
+ end
56
+
57
+ def portrait?
58
+ Device.orientation == :portrait || Device.orientation == :unknown
59
+ end
60
+
61
+ ORIENTATIONS = {
62
+ UIDeviceOrientationUnknown => :unkown,
63
+ UIDeviceOrientationPortrait => :portrait,
64
+ UIDeviceOrientationPortraitUpsideDown => :portrait_upside_down,
65
+ UIDeviceOrientationLandscapeLeft => :landscape_Left,
66
+ UIDeviceOrientationLandscapeRight => :landscape_right,
67
+ UIDeviceOrientationFaceUp => :face_up,
68
+ UIDeviceOrientationFaceDown => :face_down
69
+ }
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,74 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ # I'm purposly not including Enumerable,
4
+ # please use to_a if you want one
5
+
6
+ def <<(value)
7
+ selected << value if value.is_a?(UIView)
8
+ self
9
+ end
10
+
11
+ # @example
12
+ # rmq(UILabel)[3]
13
+ # or
14
+ # rmq(UILabel)[1..5]
15
+ def [](i)
16
+ RMQ.create_with_array_and_selectors([selected[i]], @selectors, @context)
17
+ end
18
+ alias :eq :[]
19
+
20
+ def each(&block)
21
+ return self unless block
22
+ RMQ.create_with_array_and_selectors(selected.each(&block), @selectors, @context)
23
+ end
24
+
25
+ def map(&block)
26
+ return self unless block
27
+ RMQ.create_with_array_and_selectors(selected.map(&block), @selectors, @context)
28
+ end
29
+ alias :collect :map
30
+
31
+ def select(&block)
32
+ return self unless block
33
+ RMQ.create_with_array_and_selectors(selected.select(&block), @selectors, @context)
34
+ end
35
+
36
+ def detect(&block) # Unlike enumerable, detect and find are not the same. See find in transverse
37
+ return self unless block
38
+ RMQ.create_with_array_and_selectors(selected.select(&block), @selectors, @context)
39
+ end
40
+
41
+ def grep(&block)
42
+ return self unless block
43
+ RMQ.create_with_array_and_selectors(selected.grep(&block), @selectors, @context)
44
+ end
45
+
46
+ def reject(&block)
47
+ return self unless block
48
+ RMQ.create_with_array_and_selectors(selected.reject(&block), @selectors, @context)
49
+ end
50
+
51
+ def inject(o, &block)
52
+ return self unless block
53
+ RMQ.create_with_array_and_selectors(selected.inject(o, &block), @selectors, @context)
54
+ end
55
+ alias :reduce :inject
56
+
57
+ def first
58
+ RMQ.create_with_array_and_selectors([selected.first], @selectors, @context)
59
+ end
60
+ def last
61
+ RMQ.create_with_array_and_selectors([selected.last], @selectors, @context)
62
+ end
63
+
64
+ def to_a
65
+ selected
66
+ end
67
+
68
+ def length
69
+ selected.length
70
+ end
71
+ alias :size :length
72
+ alias :count :length
73
+ end
74
+ end