galaaz 0.4.7 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1179 -39
  3. data/Rakefile +4 -2
  4. data/bin/grun +1 -1
  5. data/bin/gstudio +1 -1
  6. data/blogs/dev/dev.Rmd +2 -56
  7. data/blogs/dev/dev.md +32 -61
  8. data/blogs/dev/dev2.Rmd +65 -0
  9. data/blogs/dplyr/dplyr.Rmd +29 -0
  10. data/blogs/{dev/dev.html → dplyr/dplyr.html} +88 -57
  11. data/blogs/dplyr/dplyr.md +58 -0
  12. data/blogs/gknit/gknit.html +1262 -25
  13. data/blogs/gknit/gknit.md +471 -27
  14. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  15. data/blogs/manual/graph.rb +29 -0
  16. data/blogs/manual/manual.Rmd +567 -29
  17. data/blogs/manual/manual.html +743 -46
  18. data/blogs/manual/manual.md +1179 -39
  19. data/blogs/nse_dplyr/nse_dplyr.Rmd +466 -11
  20. data/blogs/nse_dplyr/nse_dplyr.html +472 -37
  21. data/blogs/nse_dplyr/nse_dplyr.md +645 -32
  22. data/blogs/ruby_plot/ruby_plot.Rmd +4 -4
  23. data/blogs/ruby_plot/ruby_plot.html +217 -2
  24. data/blogs/ruby_plot/ruby_plot.md +226 -1
  25. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
  26. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.svg +2 -2
  27. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
  28. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.svg +70 -70
  29. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
  30. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.svg +72 -72
  31. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
  32. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.svg +116 -116
  33. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
  34. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.svg +176 -176
  35. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
  36. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
  37. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.svg +236 -236
  38. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
  39. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.svg +176 -176
  40. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
  41. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.svg +160 -160
  42. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
  43. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.svg +105 -105
  44. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
  45. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.svg +121 -121
  46. data/examples/islr/ch2.spec.rb +1 -1
  47. data/examples/islr/ch3_boston.rb +4 -4
  48. data/examples/islr/x_y_rnorm.jpg +0 -0
  49. data/lib/R_interface/r.rb +1 -1
  50. data/lib/R_interface/r_methods.rb +2 -2
  51. data/lib/R_interface/rdata_frame.rb +8 -5
  52. data/lib/R_interface/rindexed_object.rb +1 -2
  53. data/lib/R_interface/rlist.rb +1 -0
  54. data/lib/R_interface/robject.rb +0 -1
  55. data/lib/R_interface/rpkg.rb +14 -6
  56. data/lib/R_interface/rsupport.rb +7 -9
  57. data/lib/R_interface/ruby_extensions.rb +17 -5
  58. data/lib/gknit/knitr_engine.rb +9 -2
  59. data/lib/util/exec_ruby.rb +2 -2
  60. data/specs/r_dataframe.spec.rb +173 -0
  61. data/specs/r_list.spec.rb +4 -4
  62. data/specs/ruby_expression.spec.rb +2 -11
  63. data/specs/tmp.rb +76 -34
  64. data/version.rb +1 -1
  65. metadata +17 -6
  66. data/blogs/dev/dev_files/figure-html/bubble-1.png +0 -0
  67. data/blogs/dev/dev_files/figure-html/diverging_bar. +0 -0
  68. data/blogs/dev/dev_files/figure-html/diverging_bar.png +0 -0
@@ -121,7 +121,7 @@ context "ISLR" do
121
121
  it "should create a jpeg file" do
122
122
  R.jpeg("/home/rbotafogo/desenv/galaaz/examples/islr/x_y_rnorm.jpg")
123
123
  R.df = R.data__frame(x: R.rnorm(100), y: R.rnorm(100))
124
- puts R.qplot(:df.x, :df.y, col: "green")
124
+ puts R.qplot(:x, :y, data: :df, col: "green")
125
125
  R.dev__off
126
126
  end
127
127
 
@@ -51,7 +51,7 @@ puts boston.medv
51
51
 
52
52
  R.awt
53
53
 
54
- puts R.qplot(:Boston.lstat, :Boston.medv, col: "red") +
54
+ puts R.qplot(:lstat, :medv, data: :Boston, col: "red") +
55
55
  R.geom_abline(intercept: boston_lm.coef[1],
56
56
  slope: boston_lm.coef[2],
57
57
  color: "blue",
@@ -66,13 +66,13 @@ sleep(2)
66
66
  R.grid__newpage
67
67
 
68
68
  R.my_data = R.data__frame(pred: R.predict(boston_lm), res: R.residuals(boston_lm))
69
- puts R.qplot(:my_data.pred, :my_data.res)
69
+ puts R.qplot(:pred, :res, data: :my_data)
70
70
 
71
71
  sleep(2)
72
72
  R.grid__newpage
73
73
 
74
74
  R.my_data = R.data__frame(pred: R.predict(boston_lm), res: R.rstudent(boston_lm))
75
- puts R.qplot(:my_data.pred, :my_data.res)
75
+ puts R.qplot(:pred, :res, data: :my_data)
76
76
 
77
77
  sleep(2)
78
78
  R.grid__newpage
@@ -80,7 +80,7 @@ R.grid__newpage
80
80
  vals = R.hatvalues(boston_lm)
81
81
  R.my_data = R.data__frame(size: (1..vals.size), values: vals)
82
82
  # method size returns a Numeric... size is equivalent to 'length << 0'
83
- puts R.qplot(:my_data.size, :my_data.values)
83
+ puts R.qplot(:size, :values, data: :my_data)
84
84
 
85
85
  sleep(2)
86
86
  R.grid__newpage
Binary file
@@ -23,7 +23,7 @@
23
23
 
24
24
  # Load required R libraries
25
25
  dir = File.dirname(File.expand_path('.', __FILE__))
26
- Polyglot.eval_file("#{dir}/r_libs.R")
26
+ Polyglot.eval_file('R', "#{dir}/r_libs.R")
27
27
 
28
28
  require_relative 'robject'
29
29
  require_relative 'rsupport'
@@ -80,8 +80,8 @@ module R
80
80
 
81
81
  def self.dbk_index
82
82
  Polyglot.eval("R", <<-R)
83
- function(obj, index) {
84
- obj[[index]]
83
+ function(obj, ...) {
84
+ obj[[...]]
85
85
  }
86
86
  R
87
87
  end
@@ -23,9 +23,9 @@
23
23
 
24
24
  module R
25
25
 
26
- class DataFrame < List
26
+ class DataFrame < Object
27
+ include IndexedObject
27
28
  include MDIndexedObject
28
- include Enumerable
29
29
 
30
30
  #--------------------------------------------------------------------------------------
31
31
  # Calls the R.qplot adding the data: parameter
@@ -51,13 +51,16 @@ module R
51
51
  # values, for ex., R.c(2, 3, 5)
52
52
  #--------------------------------------------------------------------------------------
53
53
 
54
- def []=(index, values)
55
-
54
+ def []=(index, *args)
55
+ values = args[-1]
56
+ idx2 = (args.size > 1)? args[-2] : false
57
+
56
58
  # dealing with double indexing function '[['
57
59
  if (index.is_a? Array)
58
60
  setR_name("`[[<-`", R.empty_symbol, *index, values)
59
61
  else
60
- setR_name("`[<-`", R.empty_symbol, index, values)
62
+ idx2 ? setR_name("`[<-`", index, idx2, values) :
63
+ setR_name("`[<-`", R.empty_symbol, index, values)
61
64
  end
62
65
 
63
66
  self
@@ -38,8 +38,7 @@ module R
38
38
 
39
39
  # dealing with double indexing function '[['
40
40
  if (index.is_a? Array)
41
- R::Support.exec_function(R::Support.dbk_index, @r_interop,
42
- R.internal_eval(:c, *index))
41
+ R::Support.exec_function(R::Support.dbk_index, @r_interop, *index)
43
42
  else
44
43
  R::Support.exec_function_name("`[`", @r_interop, index)
45
44
  end
@@ -29,6 +29,7 @@ module R
29
29
 
30
30
  class List < Object
31
31
  include IndexedObject
32
+ include Enumerable
32
33
 
33
34
  #--------------------------------------------------------------------------------------
34
35
  #
@@ -149,7 +149,6 @@ module R
149
149
  #--------------------------------------------------------------------------------------
150
150
 
151
151
  def method_missing(symbol, *args, &block)
152
-
153
152
  name = R::Support.convert_symbol2r(symbol)
154
153
 
155
154
  # Need to raise a NoMethodError when method_missing is called by an implicit
@@ -28,16 +28,25 @@ module R
28
28
  #
29
29
  #----------------------------------------------------------------------------------------
30
30
 
31
- class Pkg
31
+ class Package
32
32
 
33
- def initialize(pkg_name)
34
- @pkg_name = pkg_name
33
+ @@packages = {}
34
+
35
+ def self.[](package_name)
36
+ return @@packages[package_name] if @@packages.has_key?(package_name)
37
+ @@packages[package_name] = new(package_name)
35
38
  end
36
39
 
40
+ def initialize(package_name)
41
+ @package_name = package_name
42
+ end
43
+
37
44
  def method_missing(symbol, *args)
38
- p "execute #{@pkg_name}.#{symbol}(#{args})"
45
+ R::Support.exec_function_name("#{@package_name}::#{symbol}", *args)
39
46
  end
40
47
 
48
+ private_class_method :new
49
+
41
50
  end
42
51
 
43
52
  #----------------------------------------------------------------------------------------
@@ -45,8 +54,7 @@ module R
45
54
  #----------------------------------------------------------------------------------------
46
55
 
47
56
  def self.const_missing(name)
48
- p name
49
- Pkg.new(name)
57
+ R::Package[name.to_s.downcase]
50
58
  end
51
59
 
52
60
  end
@@ -29,7 +29,7 @@ module R
29
29
  # as [x, ]. What follows the ',' is an empty_symbol. Whenever we use in Ruby the
30
30
  # :all symbol, it will be converted to an empty_symbol in R.
31
31
  #--------------------------------------------------------------------------------------
32
-
32
+ =begin
33
33
  @@empty_symbol = Polyglot.eval("R", <<-R)
34
34
  __missing_arg = quote(f(,0));
35
35
  __missing_arg[[2]]
@@ -38,7 +38,12 @@ module R
38
38
  def self.empty_symbol
39
39
  @@empty_symbol
40
40
  end
41
+ =end
41
42
 
43
+ def self.empty_symbol
44
+ Polyglot.eval("R", "missing_arg()")
45
+ end
46
+
42
47
  # When evaluating to NA, Interop treats it as FALSE. This breaks all expectations
43
48
  # about NA. We need to protect NA from Interop unboxing. Class NotAvailable
44
49
  # puts a list around NA, so that no unboxing occurs.
@@ -63,24 +68,17 @@ module R
63
68
  # and allows for debugging. Use it in exec_function when debugging is needed.
64
69
  @@exec_from_ruby = Polyglot.eval("R", <<-R)
65
70
  function(build_method, ...) {
66
- # print(build_method);
67
- # print("exec_from_ruby");
68
- # args = list(...);
69
- # print(args);
70
-
71
71
  # function 'invoke' from package rlang should do a cleaner than
72
72
  # do.call (this is what the documentation says).
73
73
  # res = do.call(...);
74
74
  res = invoke(...);
75
-
76
- # print(res);
77
75
  res2 = build_method(res);
78
- # print(res2);
79
76
  res2
80
77
  }
81
78
  R
82
79
 
83
80
  #----------------------------------------------------------------------------------------
81
+ # @TODO: Fix the 'rescue' clause and open issue with fastR
84
82
  # Evaluates an R code
85
83
  # @param string [String] A string of R code that can be correctly parsed by R
86
84
  #----------------------------------------------------------------------------------------
@@ -20,7 +20,7 @@
20
20
  # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
21
21
  # OR MODIFICATIONS.
22
22
  ##########################################################################################
23
-
23
+ #=begin
24
24
  module Kernel
25
25
 
26
26
  def puts(*args)
@@ -29,7 +29,7 @@ module Kernel
29
29
  end
30
30
 
31
31
  end
32
-
32
+ #=end
33
33
  #==========================================================================================
34
34
  #
35
35
  #==========================================================================================
@@ -185,24 +185,36 @@ class Symbol
185
185
 
186
186
  def method_missing(symbol, *args, &block)
187
187
 
188
+ =begin
188
189
  if (symbol =~ /(.*)=$/)
189
190
  # method_missing_assign($1, args[0])
190
191
  elsif (args.length == 0 && ((R.c(symbol.to_s)._ :in, R.names(self)) >> 0))
191
192
  return self[symbol.to_s]
192
193
  end
194
+ =end
193
195
 
194
- R.send(symbol.to_s, self, *args)
196
+ E.send(symbol.to_s, self, *args)
195
197
 
196
198
  end
197
199
 
198
200
  #--------------------------------------------------------------------------------------
199
- #
201
+ # Used when selecting column in a data frame, from the first column to the var2
202
+ # column
200
203
  #--------------------------------------------------------------------------------------
201
204
 
202
- def inter(var2)
205
+ def up_to(var2)
203
206
  R::Support.exec_function(R::Support.range, self, var2)
204
207
  end
208
+
209
+
210
+ #--------------------------------------------------------------------------------------
211
+ # Create an interaction between two variables in formulas
212
+ #--------------------------------------------------------------------------------------
205
213
 
214
+ def inter(var2)
215
+ R::Support.exec_function(R::Support.range, self, var2)
216
+ end
217
+
206
218
  #--------------------------------------------------------------------------------------
207
219
  # If method_missing is implemented, then we also need to implement method 'to_ary'.
208
220
  # This is because starting from ruby 1.9 the code for Array#flatten has changed,
@@ -572,9 +572,16 @@ class KnitrEngine
572
572
  plot = R.evaluate_plot_snapshot
573
573
 
574
574
  if (!(plot.is__null >> 0))
575
-
575
+ =begin
576
+ STDERR.puts "======================"
577
+ STDERR.puts "in knitr_engine: capture_plot"
578
+ STDERR.puts @fig__path
579
+ STDERR.puts @fig__path.class
580
+ STDERR.puts File.directory?(@fig__path)
581
+ =end
576
582
  # create directory for the graphics files if does not already exists
577
- unless File.directory?(@fig__path)
583
+ # unless File.directory?(@fig__path)
584
+ unless (R.dir__exists(@fig__path) >> 0)
578
585
  FileUtils.mkdir_p(@fig__path)
579
586
  end
580
587
 
@@ -22,7 +22,7 @@
22
22
  ##########################################################################################
23
23
 
24
24
  require 'stringio'
25
-
25
+ =begin
26
26
  #----------------------------------------------------------------------------------------
27
27
  # Path StringIO puts... Already opened an issue in RC12
28
28
  #----------------------------------------------------------------------------------------
@@ -71,7 +71,7 @@ class StringIO
71
71
  end
72
72
 
73
73
  end
74
-
74
+ =end
75
75
  #----------------------------------------------------------------------------------------
76
76
  # Class RubyChunk is used only as a context for all ruby chunks in the rmarkdown file.
77
77
  # This allows for chunks to access instance_variables (@)
@@ -72,6 +72,179 @@ describe R::DataFrame do
72
72
  end
73
73
 
74
74
  end
75
+
76
+ #----------------------------------------------------------------------------------------
77
+ context "Subsetting with '['" do
78
+
79
+ before(:each) do
80
+ @mtcars = ~:mtcars
81
+ end
82
+
83
+ it "should subset with [ with only the column index" do
84
+ slice = @mtcars[1]
85
+ expect(slice.typeof).to eq "list"
86
+ expect(slice.rclass).to eq "data.frame"
87
+ expect(slice.length).to eq 1
88
+ expect(slice[[1]][1]).to eq 21.0
89
+ expect(slice[[1, 1]]).to eq 21.0
90
+ # undefined columns selected (RError)
91
+ expect { slice['Mazda RX4'] }.to raise_error(RuntimeError)
92
+ expect(slice[['Mazda RX4']]).to eq nil
93
+ end
94
+
95
+ it "should subset with [ with a column range" do
96
+ slice = @mtcars[(1..3)]
97
+ expect(slice.typeof).to eq "list"
98
+ expect(slice.rclass).to eq "data.frame"
99
+ expect(slice.length).to eq 3
100
+ expect(slice[[2]][10]).to eq 6.0
101
+ expect(slice[10, 2]).to eq 6.0
102
+ end
103
+
104
+ it "should subset with [ by row and column indices" do
105
+ expect(@mtcars[1, 1]).to eq 21.0
106
+ expect(@mtcars[6, 5]).to eq 2.76
107
+ end
108
+
109
+ it "do not use R style missing value idexing with [" do
110
+ # This array bellow is equivalent to [6]. This can bring some surprises for
111
+ # R people that are used to this indexing notation, as in this case the ','
112
+ # is ignored
113
+ arr = [6, ]
114
+ expect(arr).to eq [6]
115
+
116
+ # This will output the sixth column of the mtcars dataframe
117
+ slice = @mtcars[6, ]
118
+ expect(slice.typeof).to eq "list"
119
+ expect(slice.rclass).to eq "data.frame"
120
+ expect(slice.length).to eq 1
121
+ expect(slice[[1]][1]).to eq 2.62
122
+ end
123
+
124
+ it "should subset with [ by row index and :all" do
125
+ # Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
126
+ slice = @mtcars[5, :all]
127
+ expect(slice.rclass).to eq "data.frame"
128
+ expect(slice[1, 1]).to eq 18.7
129
+ expect(slice[1, 1]).not_to eq 360.0
130
+ expect(slice.names).to eq R.c("mpg", "cyl", "disp", "hp", "drat",
131
+ "wt", "qsec", "vs", "am", "gear", "carb")
132
+ end
133
+
134
+ it "should subset with [ by row index, :all and allowing for drop parameter" do
135
+ # will transform the data into a list
136
+ lst = @mtcars[1, :all, drop: true]
137
+ expect(lst.typeof).to eq "list"
138
+ expect(lst[[1]]).to eq 21.0
139
+ expect(lst[1]).to eq R.list(mpg: 21.0)
140
+ end
141
+
142
+ it "should subset with [ by :all and column index" do
143
+ # [1] 110 110 93 110 175 105 245 62 95 123 123 180 180 180 205 215 230 66 52
144
+ # [20] 65 97 150 150 245 175 66 91 113 264 175 335 109
145
+ slice = @mtcars[:all, 4]
146
+ expect(slice.rclass).to eq "numeric"
147
+ expect(slice.typeof).to eq "double"
148
+ expect(slice[10]).to eq 123.0
149
+ end
150
+
151
+ it "should subset with [ by :all, column index and allowing for 'drop' parameter" do
152
+ expect(@mtcars[:all, 1]).to eq @mtcars[:all, 1, drop: true]
153
+ end
154
+
155
+ it "should subset with [ and column name" do
156
+ slice = @mtcars['drat']
157
+ expect(slice.typeof).to eq "list"
158
+ expect(slice.rclass).to eq "data.frame"
159
+ expect(slice.length).to eq 1
160
+ expect(slice[[1]][1]).to eq 3.90
161
+ expect(slice[[1, 1]]).to eq 3.90
162
+ # undefined columns selected (RError)
163
+ expect { slice['Mazda RX4'] }.to raise_error(RuntimeError)
164
+ expect(slice[['Mazda RX4']]).to eq nil
165
+ end
166
+
167
+ it "should subset with [ and row name" do
168
+ slice = @mtcars['Merc 450SE', :all]
169
+ expect(slice[[1]]).to eq 16.4
170
+ expect(slice[['hp']]).to eq 180.0
171
+ end
172
+
173
+ it "should subset with [ and row and column name" do
174
+ slice = @mtcars['Merc 450SL', 'drat']
175
+ expect(slice).to eq 3.07
176
+ end
177
+
178
+ end
179
+
180
+ #----------------------------------------------------------------------------------------
181
+ context "Subsetting with '[['" do
182
+
183
+ before(:each) do
184
+ @mtcars = ~:mtcars
185
+ end
186
+
187
+ it "should subset with [[ and a column index" do
188
+ slice = @mtcars[[1]]
189
+ expect(slice.typeof).to eq "double"
190
+ expect(slice.rclass).to eq "numeric"
191
+ expect(slice[1]).to eq 21.0
192
+ expect(slice[16]).to eq 10.4
193
+ end
194
+
195
+ it "should subset with [[ and a row index" do
196
+ slice = @mtcars
197
+ end
198
+
199
+ it "should subset with [[ and row and column indices" do
200
+ expect(@mtcars[[6, 1]]).to eq 18.1
201
+ expect(@mtcars[[6, 5]]).to eq 2.76
202
+ expect(@mtcars[[15, 1]]).to eq 10.4
203
+ expect(@mtcars[[15, 7]]).to eq 17.98
204
+ end
205
+
206
+ it "should subset with [[ and row and column names" do
207
+ expect(@mtcars[['Valiant', 'mpg']]).to eq 18.1
208
+ expect(@mtcars[['Valiant', 'drat']]).to eq 2.76
209
+ expect(@mtcars[['Cadillac Fleetwood', 'mpg']]).to eq 10.4
210
+ expect(@mtcars[['Cadillac Fleetwood', 'qsec']]).to eq 17.98
211
+ end
212
+
213
+ end
214
+
215
+ #----------------------------------------------------------------------------------------
216
+ context "Assigning with '[<-'" do
217
+
218
+ before(:each) do
219
+ @mtcars = ~:mtcars
220
+ end
221
+
222
+ it "should add a column to a dataframe indexing by column" do
223
+ @mtcars["New Column"] = R.c((1..32))
224
+ expect(@mtcars[[1, 12]]).to eq 1
225
+ expect(@mtcars[['Mazda RX4', 'New Column']]).to eq 1
226
+ end
227
+
228
+ it "should add a column to a dataframe indexing with :all in the row" do
229
+ @mtcars[:all, 'New Column'] = R.c((1..32))
230
+ expect(@mtcars[[1, 12]]).to eq 1
231
+ expect(@mtcars[['Mazda RX4', 'New Column']]).to eq 1
232
+ end
233
+
234
+ it "should assign to an element of a dataframe indexing with row and column by number" do
235
+ @mtcars[17, 6] = 1000
236
+ expect(@mtcars[[17, 6]]).to eq 1000.0
237
+ expect(@mtcars[['Chrysler Imperial', 'wt']]).to eq 1000.0
238
+ end
239
+
240
+ it "should assign to a range" do
241
+ @mtcars[(10..12)] = R.list((1..32), nil, "New Col": R.c(32..1))
242
+ expect(@mtcars[['Fiat 128', 'gear']]).to eq 18
243
+ expect(@mtcars[['Chrysler Imperial', 'New Col']]).to eq 16
244
+ end
245
+
246
+ end
247
+
75
248
  #----------------------------------------------------------------------------------------
76
249
  context "Ruby 'each'" do
77
250