ruby_mvc 0.0.0

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.
Files changed (42) hide show
  1. data/LICENSE +19 -0
  2. data/README.md +69 -0
  3. data/lib/ruby_mvc.rb +33 -0
  4. data/lib/ruby_mvc/application.rb +53 -0
  5. data/lib/ruby_mvc/controllers/app_controller.rb +93 -0
  6. data/lib/ruby_mvc/controllers/rails_controller.rb +71 -0
  7. data/lib/ruby_mvc/models.rb +28 -0
  8. data/lib/ruby_mvc/models/array_table_model.rb +59 -0
  9. data/lib/ruby_mvc/models/keyed_array_table_model.rb +83 -0
  10. data/lib/ruby_mvc/models/table_model.rb +42 -0
  11. data/lib/ruby_mvc/module.rb +35 -0
  12. data/lib/ruby_mvc/renderers.rb +26 -0
  13. data/lib/ruby_mvc/renderers/html4_table_model_renderer.rb +100 -0
  14. data/lib/ruby_mvc/toolkit.rb +31 -0
  15. data/lib/ruby_mvc/toolkit/app.rb +32 -0
  16. data/lib/ruby_mvc/toolkit/dialog.rb +31 -0
  17. data/lib/ruby_mvc/toolkit/frame.rb +34 -0
  18. data/lib/ruby_mvc/toolkit/notification.rb +202 -0
  19. data/lib/ruby_mvc/toolkit/peers/wxruby.rb +31 -0
  20. data/lib/ruby_mvc/toolkit/peers/wxruby/app.rb +44 -0
  21. data/lib/ruby_mvc/toolkit/peers/wxruby/box_layout.rb +48 -0
  22. data/lib/ruby_mvc/toolkit/peers/wxruby/common.rb +72 -0
  23. data/lib/ruby_mvc/toolkit/peers/wxruby/frame.rb +49 -0
  24. data/lib/ruby_mvc/toolkit/peers/wxruby/web_view.rb +87 -0
  25. data/lib/ruby_mvc/toolkit/web_view.rb +60 -0
  26. data/lib/ruby_mvc/toolkit/widget.rb +108 -0
  27. data/lib/ruby_mvc/views.rb +85 -0
  28. data/lib/ruby_mvc/views/ar_model_editor.rb +84 -0
  29. data/lib/ruby_mvc/views/ar_type_editor.rb +65 -0
  30. data/lib/ruby_mvc/views/ar_type_list.rb +45 -0
  31. data/lib/ruby_mvc/views/table_view.rb +96 -0
  32. data/lib/ruby_mvc/views/web_view.rb +65 -0
  33. data/lib/ruby_mvc/wx.rb +26 -0
  34. data/ruby_mvc.gemspec +37 -0
  35. data/sample/frame.rb +28 -0
  36. data/sample/mvc.rb +29 -0
  37. data/sample/test.html +118 -0
  38. data/sample/web_view.rb +34 -0
  39. data/test/unit/models/test_array_table_model.rb +56 -0
  40. data/test/unit/models/test_keyed_array_table_model.rb +54 -0
  41. data/test/unit/test_array_table_model.rb +38 -0
  42. metadata +107 -0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ ######################################################################
2
+ #
3
+ # Copyright 2011 Andrew S. Townley
4
+ #
5
+ # Permission to use, copy, modify, and disribute this software for
6
+ # any purpose with or without fee is hereby granted, provided that
7
+ # the above copyright notices and this permission notice appear in
8
+ # all copies.
9
+ #
10
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
11
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
14
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
16
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
+ #
19
+ ######################################################################
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+
2
+ README for Ruby MVC
3
+ ===================
4
+
5
+ This project is based on previous work on [Shoes
6
+ MVC](https://github.com/atownley/shoes_mvc), but now does not
7
+ use the Shoes toolkit. At the moment, it achieves a minimal set of
8
+ cross-platform functionality based on using the wxRuby gem. There are
9
+ plans to make this change in the future, but right now, the goal is
10
+ just to get something working.
11
+
12
+ *NOTE: this code is **highly experimental** and an early work
13
+ in progress. It may or may not ever be completed, and it may
14
+ or may not ever be useful.*
15
+
16
+ DEPENDENCIES
17
+ ============
18
+
19
+ You'll need to have the following gems installed to use this library:
20
+
21
+ - activerecord (to use the Rails integration)
22
+ - tagz (for the HTML rendering)
23
+ - wxruby (use wxruby-ruby19 for Ruby 1.9)
24
+ - sqlite3 (to use the SQLite3 drivers)
25
+
26
+ Platform Notes
27
+ --------------
28
+
29
+ There are some tweaks required using the library with various
30
+ environments. The known ones are highlighted below.
31
+
32
+ ### Ruby 1.8.7
33
+
34
+ Apparently, there's a change in 1.8.7 that causes trouble with SWIG
35
+ libraries: http://www.ruby-forum.com/topic/161876. You may or may not
36
+ hit this problem running 1.8.7, as it appears to be rather
37
+ intermittent.
38
+
39
+
40
+ ### MacOS X
41
+
42
+ If you're using this on a 64-bit version of OSX, you'll want to make
43
+ sure you do the following when you're installing the dependency gems:
44
+
45
+ $ env ARCHFLAGS="-arch x86_64 -arch i686" gem install --no-ri --no-rdoc
46
+
47
+ The above line will ensure that when you run in 32-bit mode for
48
+ wxRuby, that things will all work as expected.
49
+
50
+ Additionally, you might consider an alias like the following somewhere
51
+ handy like .profile or .bashrc
52
+
53
+ $ alias wxruby="arch -i386 ruby -rubygems"
54
+
55
+ This link is also useful if using rvm and ruby 1.9.x:
56
+ http://www.ruby-forum.com/topic/212707#969982. The magic is this
57
+ command:
58
+
59
+ $ rvm install ruby-1.9.2-head -C --with-arch=x86_64,i386
60
+
61
+ Once you do the above, you should be able to successfully install the
62
+ wxruby-ruby19 gem using the following platform magic:
63
+
64
+ $ gem install --platform x86-darwin-9 --no-ri --no-rdoc wxruby-ruby19
65
+
66
+ ### Windows
67
+
68
+ Amazingly enough, it seems to *just work* on Windows (Vista is the
69
+ only tested configuration at the moment). YMMV.
data/lib/ruby_mvc.rb ADDED
@@ -0,0 +1,33 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 2011 Andrew S. Townley
5
+ #
6
+ # Permission to use, copy, modify, and disribute this software for
7
+ # any purpose with or without fee is hereby granted, provided that
8
+ # the above copyright notices and this permission notice appear in
9
+ # all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
12
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
15
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
+ #
20
+ # File: ruby_mvc.rb
21
+ # Created: Sat 19 Nov 2011 11:24:19 GMT
22
+ #
23
+ ######################################################################
24
+ #++
25
+
26
+ require 'yaml'
27
+ require 'ruby_mvc/module'
28
+ require 'ruby_mvc/toolkit'
29
+ require 'ruby_mvc/renderers'
30
+ require 'ruby_mvc/controllers/app_controller'
31
+ require 'ruby_mvc/models'
32
+ require 'ruby_mvc/views'
33
+ require 'ruby_mvc/application'
@@ -0,0 +1,53 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 2011 Andrew S. Townley
5
+ #
6
+ # Permission to use, copy, modify, and disribute this software for
7
+ # any purpose with or without fee is hereby granted, provided that
8
+ # the above copyright notices and this permission notice appear in
9
+ # all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
12
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
15
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
+ #
20
+ # File: application.rb
21
+ # Created: Wed 23 Nov 2011 11:01:20 GMT
22
+ #
23
+ ######################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+
28
+ # This provides the entry point for a basic application.
29
+ class Application
30
+ attr_accessor :frame
31
+ attr_accessor :controller
32
+
33
+ def initialize(options, &block)
34
+ self.frame = Toolkit::Frame.new(options)
35
+ if cc = options[:controller]
36
+ self.controller = cc
37
+ self.controller.app = self
38
+ self.controller.init
39
+ end
40
+ self.instance_eval(&block) if block
41
+ self.frame.show
42
+ end
43
+ end
44
+
45
+ # This method creates a default application and runs it
46
+ # using the active toolkit.
47
+
48
+ def self.app(*args, &block)
49
+ Toolkit::App.new do
50
+ Application.new(*args, &block)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,93 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 2011 Andrew S. Townley
5
+ #
6
+ # Permission to use, copy, modify, and disribute this software for
7
+ # any purpose with or without fee is hereby granted, provided that
8
+ # the above copyright notices and this permission notice appear in
9
+ # all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
12
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
15
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
+ #
20
+ # File: app_controller.rb
21
+ # Created: Sat 19 Nov 2011 11:29:49 GMT
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+
28
+ # This module takes care of dispatching links to controller
29
+ # classes.
30
+
31
+ module LinkDispatcher
32
+ # This method is a callback to allow links embedded in
33
+ # views to trigger controller actions in a loosely-coupled
34
+ # manner.
35
+ #
36
+ # The default implementation will attempt to call methods
37
+ # based on applying the RubyMVC#method_name
38
+ # transformation and checking if the controller responds
39
+ # to the method. To manually dispatch the method, simply
40
+ # override this method in the derived class.
41
+
42
+ def link_activated(sender, link)
43
+ puts "#link_activated(#{sender}, #{link})"
44
+ m = RubyMVC.method_name(link).to_sym
45
+ if self.respond_to? m
46
+ self.send(m, sender, link)
47
+ end
48
+ end
49
+ end
50
+
51
+ class AppController
52
+ include LinkDispatcher
53
+
54
+ attr_accessor :app
55
+
56
+ # By convention, the application is configured using an
57
+ # app.yml file in the same directory as the application
58
+ # controller.
59
+
60
+ def initialize(app_file)
61
+ @config_file = File.expand_path(File.join(File.dirname(app_file), "../app.yml"))
62
+ if !File.exist? @config_file
63
+ @shoes.alert("Unable to locate configuration file.\nFile '#{@config_file}' not found.")
64
+ @shoes.exit
65
+ end
66
+
67
+ @config = YAML.load(File.new(@config_file))
68
+ setup
69
+ run
70
+ end
71
+
72
+ # This method is a placeholder for the actual
73
+ # initialization to be performed by the Ruby application
74
+ # itself. It is called automatically by the constructor
75
+ # of the application controller.
76
+
77
+ def run
78
+ end
79
+
80
+ protected
81
+ def config
82
+ @config || {}
83
+ end
84
+
85
+ # This method is called prior to calling the #run method
86
+ # to give the derived controller classes an opportunity to
87
+ # perform any specific initialization.
88
+
89
+ def setup
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,71 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 2011 Andrew S. Townley
5
+ #
6
+ # Permission to use, copy, modify, and disribute this software for
7
+ # any purpose with or without fee is hereby granted, provided that
8
+ # the above copyright notices and this permission notice appear in
9
+ # all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
12
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
15
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
+ #
20
+ # File: rails_controller.rb
21
+ # Created: Sat 19 Nov 2011 11:29:49 GMT
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ require 'active_record'
27
+
28
+ module RubyMVC
29
+
30
+ # This controller is used to assist in writing Ruby
31
+ # applications for an existing Rails application. All of
32
+ # the models will be automatically loaded based on the
33
+ # directory configuration of the Rails environment, and the
34
+ # database connection environment will be used.
35
+ #
36
+ # This controller uses the following configuration settings
37
+ # to help it initialize itself:
38
+ #
39
+ # rails_app - the location of the app directory of the Rails
40
+ # application
41
+ #
42
+ # config - the default database configuration to use by
43
+ # the application
44
+
45
+ class RailsController < AppController
46
+ def setup
47
+ @rails_app = File.expand_path(File.join(
48
+ File.dirname(@config_file), config["rails_app"]))
49
+ connect_db
50
+ load_models
51
+ end
52
+
53
+ private
54
+ def connect_db
55
+ yml = File.expand_path(File.join(@rails_app, "../config/database.yml"))
56
+ dbconf = YAML.load(File.new(yml))
57
+ env = dbconf[config["config"]]
58
+
59
+ case(env["adapter"])
60
+ when "sqlite3"
61
+ env["database"] = File.join("#{@rails_app}/..", env["database"])
62
+ end
63
+ ActiveRecord::Base.establish_connection(env)
64
+ end
65
+
66
+ def load_models
67
+ Dir.glob(File.join(@rails_app, "models/*.rb")) { |m| require m }
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,28 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 2011 Andrew S. Townley
5
+ #
6
+ # Permission to use, copy, modify, and disribute this software for
7
+ # any purpose with or without fee is hereby granted, provided that
8
+ # the above copyright notices and this permission notice appear in
9
+ # all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
12
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
15
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
+ #
20
+ # File: models.rb
21
+ # Created: Sat 19 Nov 2011 19:50:32 GMT
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ require 'ruby_mvc/models/table_model'
27
+ require 'ruby_mvc/models/array_table_model'
28
+ require 'ruby_mvc/models/keyed_array_table_model'
@@ -0,0 +1,59 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 2011 Andrew S. Townley
5
+ #
6
+ # Permission to use, copy, modify, and disribute this software for
7
+ # any purpose with or without fee is hereby granted, provided that
8
+ # the above copyright notices and this permission notice appear in
9
+ # all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
12
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
15
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
+ #
20
+ # File: array_table_model.rb
21
+ # Created: Sat 19 Nov 2011 19:56:17 GMT
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module ShoesMVC
27
+ module Models
28
+
29
+ # This class implements the TableModel interface based on
30
+ # the data being stored in an array. The elements in the
31
+ # array must either be a Hash, or they must respond to the
32
+ # [] accessors for retrieving elements by key and implement
33
+ # a #keys method for indicating the properties in each row
34
+ # instance.
35
+
36
+ class ArrayTableModel < TableModel
37
+ def initialize(data)
38
+ @data = data
39
+ end
40
+
41
+ def keys
42
+ if @data && @data.size > 0
43
+ @data.keys
44
+ else
45
+ {}
46
+ end
47
+ end
48
+
49
+ def each(&block)
50
+ @data.each(&block)
51
+ end
52
+
53
+ def each_with_index(&block)
54
+ @data.each_with_index(&block)
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,83 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 2011 Andrew S. Townley
5
+ #
6
+ # Permission to use, copy, modify, and disribute this software for
7
+ # any purpose with or without fee is hereby granted, provided that
8
+ # the above copyright notices and this permission notice appear in
9
+ # all copies.
10
+ #
11
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
12
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14
+ # AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
15
+ # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
17
+ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18
+ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
+ #
20
+ # File: keyed_array_table_model.rb
21
+ # Created: Sat 19 Nov 2011 18:58:36 GMT
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module ShoesMVC
27
+ module Models
28
+
29
+ class KeyedArrayTableModel < TableModel
30
+
31
+ # This class provides a row adapter for each row in the
32
+ # array so that it behaves effectively like a Hash
33
+ # instance, but which still allows the underlying array to
34
+ # be manipulated without problem.
35
+
36
+ class Row
37
+ # The instance is created with an array of strings or
38
+ # symbols used to denote the keys of the model. The keys
39
+ # MUST be specified in the order of the data elements in
40
+ # the data array. When the model is asked for the value
41
+ # for a given key, the value is retrieved from the data
42
+ # array by the position of the key in the keys array.
43
+
44
+ def initialize(keys, row)
45
+ @keys = keys
46
+ @row = row
47
+ end
48
+
49
+ def [](key)
50
+ @row[@keys[key.to_sym]]
51
+ end
52
+
53
+ def []=(key, val)
54
+ @row[@keys[key.to_sym]] = val
55
+ end
56
+ end
57
+
58
+ # This method is used to initialize the mo
59
+ def initialize(keys, data)
60
+ @keys = {}
61
+ keys.each_with_index { |x, i| @keys[x.to_sym] = i }
62
+ @data = data
63
+ end
64
+
65
+ def keys
66
+ @keys.keys
67
+ end
68
+
69
+ def each(&block)
70
+ @data.each do |x|
71
+ block.call(Row.new(@keys, x))
72
+ end
73
+ end
74
+
75
+ def each_with_index(&block)
76
+ @data.each_with_index do |x, i|
77
+ block.call(Row.new(@keys, x), i)
78
+ end
79
+ end
80
+ end
81
+
82
+ end
83
+ end