fat_table 0.6.0 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f348d317c061becae08890ff02cc9c08789787d966f9ed88f3a4ef22b6eddb44
4
- data.tar.gz: bf672b4f4f4ab07df465d06904ccebb9b48507177dc88a343eb09bfb0e98bc02
3
+ metadata.gz: 9f247f30e6f34d7eb429f43a9375fdd9c61cc2be02fecf35916c896c831966a1
4
+ data.tar.gz: 97932270075de281d3f34414b991795d553ca6fd28f32766bf718942001c8d68
5
5
  SHA512:
6
- metadata.gz: c721233a04cc1664e8d8acea3cf677190aa47da30b3db7e1b9f6c13ddd56028a8ecd8b0c71915d0a1703f46fc9a22a1c3a8a3f13d6c80fb07964a22fd864ab7e
7
- data.tar.gz: 7877d4529d8a6f2a13ee0a1518730791b4e5ed7dbadd2030367593c95ccdbd5159e711f7ffe69b9b2fa9b4812a6f49d3d1a9fce46642e4454f54ff40d769a4cb
6
+ metadata.gz: 951fd4ef3540fc7dacce89f73fa9fad6185e50cff664511b8038633608357dbd70277a464c0cb27a25fbcb801f4ef738a065c66addfa0a11887cec9a0013b9bf
7
+ data.tar.gz: 88d4a6479af8e384ed33d631bfad5085971f53c9a40413f751ae421524dba65552c305a5566ce7a19a19f9f5b35406bdf5ae961ddb4edccd6e7a0784deef60ce
data/.simplecov ADDED
@@ -0,0 +1,18 @@
1
+ # -*- mode: ruby -*-
2
+
3
+ SimpleCov.start do
4
+ # any custom configs like groups and filters can be here at a central place
5
+ add_filter '/spec/'
6
+ add_filter '/tmp/'
7
+ add_group "Models", "lib/fat_table"
8
+ add_group "Core Extension", "lib/ext"
9
+ # After this many seconds between runs, old coverage stats are thrown out,
10
+ # so 3600 => 1 hour
11
+ merge_timeout 3600
12
+ # Make this true to merge rspec and cucumber coverage together
13
+ use_merging false
14
+ command_name 'Rspec'
15
+ nocov_token 'no_cover'
16
+ # Branch coverage
17
+ enable_coverage :branch
18
+ end
data/README.org CHANGED
@@ -1,6 +1,7 @@
1
1
  #+TITLE: FatTable User Guide
2
2
  #+OPTIONS: toc:4
3
3
  #+LATEX_HEADER: \usepackage[margin=0.75in]{geometry}
4
+ #+LATEX_HEADER: \usepackage[utf8]{inputenc}
4
5
  #+PROPERTY: header-args:ruby :colnames no :session readme :hlines yes :exports both
5
6
  #+PROPERTY: header-args:sh :exports code
6
7
  #+STARTUP: inlineimages
@@ -33,7 +34,7 @@ The following is for org.
33
34
 
34
35
  #+RESULTS:
35
36
  #+begin_EXAMPLE
36
- Current version is: 0.6.0
37
+ Current version is: 0.6.3
37
38
  #+end_EXAMPLE
38
39
 
39
40
  * Introduction
@@ -105,8 +106,9 @@ org-mode buffer as an org-table, ready for processing by other code blocks.
105
106
  - [[#example-input-tables][Example Input Tables]]
106
107
  - [[#select][Select]]
107
108
  - [[#selecting-existing-columns-also-of-omni][Selecting Existing Columns (Also of :omni)]]
108
- - [[#copying-and-renaming-existing-columns][Copying and Renaming Existing Columns]]
109
+ - [[#copying-and-renaming-existing-columns][Copying and Renaming Existing Columns.]]
109
110
  - [[#adding-new-columns][Adding New Columns]]
111
+ - [[#adding-constant-strings-and-other-types-in-select][Adding Constant Strings and Other Types in select]]
110
112
  - [[#custom-instance-variables-and-hooks][Custom Instance Variables and Hooks]]
111
113
  - [[#argument-order-and-boundaries][Argument Order and Boundaries]]
112
114
  - [[#where][Where]]
@@ -531,6 +533,7 @@ each group.
531
533
  ** Constructing Tables
532
534
  *** Empty Tables
533
535
  **** Without Headers
536
+
534
537
  You can create an empty table with ~FatTable::Table.new~ or, the shorter form,
535
538
  ~FatTable.new~, and then add rows with the ~<<~ operator and a Hash. The keys
536
539
  in the added rows determine the names of the headers:
@@ -586,6 +589,7 @@ for which no key was give are assigned ~nil~ as well:
586
589
  #+end_EXAMPLE
587
590
 
588
591
  **** With Headers
592
+
589
593
  Alternatively, you can specify the headers at the outset, in which case,
590
594
  headers in added rows that do not match any of the initial headers cause new
591
595
  columns to be created:
@@ -619,6 +623,7 @@ columns to be created:
619
623
  #+end_EXAMPLE
620
624
 
621
625
  **** Forcing String Type
626
+
622
627
  Occasionally, ~FatTable~'s automatic type detection can get in the way and you
623
628
  just want it to treat one or more columns as Strings regardless of their
624
629
  appearance. Think, for example, of zip codes. If headers are given when a
@@ -658,6 +663,7 @@ exisiting items in the column are converted to strings with the #to_s method.
658
663
  #+end_EXAMPLE
659
664
 
660
665
  **** Designating "Tolerant" Columns
666
+
661
667
  Related to the problem just discussed is the problem of reading files in from
662
668
  the wild where a column may get typed as, say Numeric, but then contain
663
669
  something that can't be parsed as a Numeric. ~FatTable~ raises an exception
@@ -790,12 +796,13 @@ header row, and the headers are converted to symbols as described above.
790
796
 
791
797
  *** From Arrays of Arrays
792
798
  **** In Ruby Code
799
+
793
800
  You can also initialize a table directly from ruby data structures. You can,
794
801
  for example, build a table from an array of arrays. Remember that you can
795
802
  make any column tolerant with a ~tolerant_columns:~ keyword argument or make
796
803
  them all tolerant by designating the pseudo-column ~:*~ as tolerant.
797
804
 
798
- #+BEGIN_SRC ruby
805
+ #+BEGIN_SRC ruby :eval never
799
806
  aoa = [
800
807
  ['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
801
808
  [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ENTITY1', 'T'],
@@ -818,11 +825,14 @@ Notice that the values can either be ruby objects, such as the Integer ~85_000~,
818
825
  or strings that can be parsed into one of the permissible column types.
819
826
 
820
827
  **** In Emacs Org Files
828
+
821
829
  This method of building a table, ~.from_aoa~, is particularly useful in dealing
822
830
  with Emacs org-mode code blocks. Tables in org-mode are passed to code blocks as
823
831
  arrays of arrays. Likewise, a result of a code block in the form of an array of
824
832
  arrays is displayed as an org-mode table:
825
833
 
834
+ #+ATTR_LATEX: :environment footnotesize
835
+ #+ATTR_LATEX: :environment verbatim
826
836
  #+BEGIN_EXAMPLE
827
837
  #+NAME: trades1
828
838
  | Ref | Date | Code | Price | G10 | QP10 | Shares | LP | QP | IPLP | IPQP |
@@ -985,6 +995,7 @@ keyword argument or make them all tolerant by designating the pseudo-column
985
995
 
986
996
  *** Marking Groups in Input
987
997
  **** Manually
998
+
988
999
  At any point, you can add a boundary to a table by invokong the
989
1000
  ~mark_boundary~ method. Without an argument, it adds the boundary to the end
990
1001
  of the table; with a numeric argument, ~n~, it adds the boundary after row
@@ -1180,6 +1191,7 @@ table, rearrange their order, and create new columns that are a function of
1180
1191
  other columns.
1181
1192
 
1182
1193
  **** Selecting Existing Columns (Also of :omni)
1194
+
1183
1195
  Here we select three existing columns by simply passing header symbols in the
1184
1196
  order we want them to appear in the output. Thus, one use of =select= is to
1185
1197
  filter and permute the order of existing columns. The =select= method preserves
@@ -1256,7 +1268,8 @@ you cannot add additional column names:
1256
1268
  | T016 | 2016-11-02 | P | 8.25 | T | T | 100 | 14 | 86 | 0.2453 | 0.1924 | 825.0 |
1257
1269
  #+end_EXAMPLE
1258
1270
 
1259
- **** Copying and Renaming Existing Columns
1271
+ **** Copying and Renaming Existing Columns.
1272
+
1260
1273
  After the list of selected column names in the call to ~select~, you can add
1261
1274
  any number of hash-like arguments. You can use these to add a copy of an
1262
1275
  existing column. By calling select again, you can include only the copied
@@ -1296,6 +1309,7 @@ changed to ~:id~, just add an argument to define the new ~:id~ column:
1296
1309
  #+end_EXAMPLE
1297
1310
 
1298
1311
  **** Adding New Columns
1312
+
1299
1313
  More interesting is that ~select~ can take hash-like keyword arguments after
1300
1314
  the symbol arguments to create new columns in the output as functions of other
1301
1315
  columns. For each hash-like parameter, the keyword given must be a symbol,
@@ -1387,7 +1401,32 @@ second, chained call to ~select~:
1387
1401
  | T016 | 2016-11-02 | 8.25 | 100 | 825.0 |
1388
1402
  #+end_EXAMPLE
1389
1403
 
1404
+ **** Adding Constant Strings and Other Types in select
1405
+
1406
+ Because ~select~'s hash-like parameters evaluate a string as a ruby
1407
+ expression, as just described, it must provide a way to set a new column to a
1408
+ string literal. To indicate that a string should be inserted literally, add a
1409
+ ~:~ as the first non-blank character in the string. This will supress
1410
+ evaluation and insert the remainder of the string in the named column.
1411
+
1412
+ #+BEGIN_SRC ruby :wrap EXAMPLE
1413
+ tab1.select(:ref, :price, :shares, traded_on: :date, cost: ':the price of freedom').
1414
+ select(:ref, :traded_on, :price, :shares, :cost).to_aoa
1415
+ #+END_SRC
1416
+
1417
+ This sets the ~:cost~ column to the string constant 'the price of freedom' for
1418
+ the whole table.
1419
+
1420
+ You can set a column to a constant of any of the acceptable types, ~Numeric~,
1421
+ ~Date~, ~DateTime~, true, false, or nil.
1422
+
1423
+ #+BEGIN_SRC ruby :wrap EXAMPLE
1424
+ tab1.select(:ref, :price, :shares, traded_on: :date, cost: Math::PI, today: Date.today).
1425
+ select(:ref, :traded_on, :price, :shares, :cost, :today).to_aoa
1426
+ #+END_SRC
1427
+
1390
1428
  **** Custom Instance Variables and Hooks
1429
+
1391
1430
  As the above examples demonstrate, the instance variables ~@row~ and ~@group~
1392
1431
  are available when evaluating expressions that add new columns. You can also set
1393
1432
  up your own instance variables as well for keeping track of things that cross
@@ -1446,6 +1485,7 @@ of the running cost of shares, then formats the table.
1446
1485
  #+END_EXAMPLE
1447
1486
 
1448
1487
  **** Argument Order and Boundaries
1488
+
1449
1489
  Notice that ~select~ can take any number of arguments but all the symbol
1450
1490
  arguments must come first followed by all the hash-like keyword arguments,
1451
1491
  including the special arguments for instance variables and hooks.
@@ -1581,7 +1621,6 @@ row, and the table is sorted as with ~order_by~ on that column.
1581
1621
  | T013 | 2016-11-02 | P | 7.35 | T | T | 53100 | 7656 | 45444 | 0.2453 | 0.1924 | 390285.0 |
1582
1622
  #+end_EXAMPLE
1583
1623
 
1584
-
1585
1624
  *** Group_by
1586
1625
  Like ~order_by~, ~group_by~ takes a set of parameters of column header symbols,
1587
1626
  the "grouping parameters", by which to sort the table into a set of groups that
@@ -1669,6 +1708,7 @@ implicit ~order_by~ on the grouping columns is collapsed into a single row.
1669
1708
 
1670
1709
  *** Join
1671
1710
  **** Join Types
1711
+
1672
1712
  So far, all the operations have operated on a single table. ~FatTable~ provides
1673
1713
  several ~join~ methods for combining two tables, each of which takes as
1674
1714
  parameters (1) a second table and (2) except in the case of ~cross_join~, zero
@@ -1705,6 +1745,7 @@ for inclusion in the joined output table.
1705
1745
  M~ rows.
1706
1746
 
1707
1747
  **** Join Expressions
1748
+
1708
1749
  For each of the join types, if no join expressions are given, the tables will be
1709
1750
  joined on columns having the same column header in both tables, and the join
1710
1751
  condition is satisfied when all the values in those columns are equal. If the
@@ -1732,6 +1773,7 @@ local variables within the expression, but the instance variables ~@row~ and
1732
1773
  ~@group~ are not.
1733
1774
 
1734
1775
  **** Join Examples
1776
+
1735
1777
  The following examples are taken from the [[https://www.tutorialspoint.com/postgresql/postgresql_using_joins.htm][Postgresql tutorial]], with some slight
1736
1778
  modifications. The examples will use the following two tables, which are also
1737
1779
  available in ~ft_console~ as ~@tab_a~ and ~@tab_b~:
@@ -2008,6 +2050,7 @@ set operations on duplicates and groups.
2008
2050
  #+END_EXAMPLE
2009
2051
 
2010
2052
  **** Unions
2053
+
2011
2054
  Two tables that are set-compatible can be combined with the ~union~ or
2012
2055
  ~union_all~ methods so that the rows of both tables appear in the output. In the
2013
2056
  output table, the headers of the receiver table are used. You can use ~select~
@@ -2099,6 +2142,7 @@ group boundary between the rows of the two input tables.
2099
2142
  #+END_EXAMPLE
2100
2143
 
2101
2144
  **** Intersections
2145
+
2102
2146
  The ~intersect~ method returns a table having only rows common to both tables,
2103
2147
  eliminating any duplicate rows in the result.
2104
2148
 
@@ -2160,6 +2204,7 @@ operation matters.
2160
2204
  #+END_EXAMPLE
2161
2205
 
2162
2206
  **** Set Differences with Except
2207
+
2163
2208
  You can use the ~except~ method to delete from a table any rows that occur in
2164
2209
  another table, that is, compute the set difference between the tables.
2165
2210
 
@@ -2322,6 +2367,7 @@ but ruby data structures, and for them, things such as alignment are irrelevant.
2322
2367
 
2323
2368
  *** Available Formatter Output Targets
2324
2369
  **** Output Media
2370
+
2325
2371
  ~FatTable~ supports the following output targets for its tables:
2326
2372
 
2327
2373
  - Text :: form the table with ACSII characters,
@@ -2342,6 +2388,7 @@ formats can be defined by adding additional classes.
2342
2388
 
2343
2389
  **** Examples
2344
2390
  ***** To Text
2391
+
2345
2392
  This formatter uses nothing by ASCII characters to draw the table. Notice
2346
2393
  that, unlike to ~to_org~ formatter shown below, the intersections of lines are
2347
2394
  represented by a ~+~ character. Embelishments such as color, bold, and so
@@ -2367,6 +2414,7 @@ forth are ignored.
2367
2414
  #+END_EXAMPLE
2368
2415
 
2369
2416
  ***** To Org
2417
+
2370
2418
  This formatter is designed to format tables in a manner consistent with the
2371
2419
  way tables are drawn within Emacs Org Mode. It also uses nothing by ASCII
2372
2420
  characters to draw the table, but, the intersections of lines are represented
@@ -2395,6 +2443,7 @@ it may be better to use that formatter as shown below.
2395
2443
  #+end_EXAMPLE
2396
2444
 
2397
2445
  ***** To Term
2446
+
2398
2447
  When outputting to a terminal or other device that can interpret ANSI
2399
2448
  characters and escape codes, you can use this formatter to get a prettier
2400
2449
  table. It also allows embelishments such as color and text styles to the
@@ -2420,6 +2469,7 @@ extent the device supports it.
2420
2469
  #+end_EXAMPLE
2421
2470
 
2422
2471
  ***** To LaTeX
2472
+
2423
2473
  This formatter outputs a table in the form suitable for inclusion in a LaTeX
2424
2474
  document using the ~logtable~ package. Natualy it allows embelishments such
2425
2475
  as color and text styles to the full extent of LaTeX's formatting prowess.
@@ -2447,6 +2497,7 @@ Finance&
2447
2497
  #+end_EXAMPLE
2448
2498
 
2449
2499
  ***** To AoA (Array of Arrays)
2500
+
2450
2501
  #+begin_SRC ruby :wrap EXAMPLE
2451
2502
  tab_b.to_aoa
2452
2503
  #+end_SRC
@@ -2457,6 +2508,7 @@ Finance&
2457
2508
  #+end_EXAMPLE
2458
2509
 
2459
2510
  ***** To AoH (Array of Hashes)
2511
+
2460
2512
  #+begin_SRC ruby :wrap EXAMPLE
2461
2513
  tab_b.to_aoh
2462
2514
  #+end_SRC
@@ -2477,6 +2529,7 @@ order, so '$R,' and ',$R' are equivalent.
2477
2529
  Here is a list of all the formatting directives that apply to each cell type:
2478
2530
 
2479
2531
  **** String
2532
+
2480
2533
  For a string element, the following instructions are valid. Note that these can
2481
2534
  also be applied to all the other cell types as well since they are all converted
2482
2535
  to a string in forming the output.
@@ -2505,6 +2558,7 @@ columns of a given type, it can be countermanded in formatting directives for
2505
2558
  particular columns.
2506
2559
 
2507
2560
  **** Numeric
2561
+
2508
2562
  For a numeric element, all the instructions valid for string are available, in
2509
2563
  addition to the following:
2510
2564
 
@@ -2523,6 +2577,7 @@ For example, the directive 'R5.0c[blue]' would right-align the numeric
2523
2577
  element, pad it on the left with zeros, and color it blue.
2524
2578
 
2525
2579
  **** DateTime
2580
+
2526
2581
  For a ~DateTime~, all the instructions valid for string are available, in
2527
2582
  addition to the following:
2528
2583
 
@@ -2538,6 +2593,7 @@ For example, 'c[pink]d[%b %-d, %Y]C', would format a date element like 'Sep
2538
2593
  22, 1957', center it, and color it pink.
2539
2594
 
2540
2595
  **** Boolean
2596
+
2541
2597
  For a boolean cell, all the instructions valid for string are available, in
2542
2598
  addition to the following:
2543
2599
 
@@ -2555,6 +2611,7 @@ render a true boolean as ~Yeppers~ colored green on pink and render a false
2555
2611
  boolean as ~Nope~ colored red on pink. See [[https://www.youtube.com/watch?v=oLdFFD8II8U][Yeppers]] for additional information.
2556
2612
 
2557
2613
  **** NilClass
2614
+
2558
2615
  By default, ~nil~ elements are rendered as blank cells, but you can make them
2559
2616
  visible with the following, and in that case, all the formatting instructions
2560
2617
  valid for strings are also available:
@@ -2565,6 +2622,7 @@ For example, you might want to use 'n[-]Cc[purple]' to make nils visible as a
2565
2622
  centered purple hyphen.
2566
2623
 
2567
2624
  *** The ~format~ and ~format_for~ methods
2625
+
2568
2626
  Formatters take only two kinds of methods, those that attach footers to a
2569
2627
  table, which are discussed in the next section, and those that specify
2570
2628
  formatting for table cells, which are the subject of this section.
@@ -2706,6 +2764,7 @@ but not for other nils, such as in the last row of the ~:join_date~ column.
2706
2764
 
2707
2765
  *** Footers
2708
2766
  **** Adding Footers
2767
+
2709
2768
  You can call the ~foot~, ~gfoot~, ~footer,~ or ~gfooter~, methods on
2710
2769
  ~Formatter~ objects to add footers and group footers. Note that all of these
2711
2770
  methods return a ~Footer~ object that can be accessed to extract the computed
@@ -2763,6 +2822,7 @@ There are also a number of convenience methods for adding common footers:
2763
2822
  columns with the label 'Group Maximum'.
2764
2823
 
2765
2824
  **** Dynamic Labels
2825
+
2766
2826
  Most of the time, you will want a fixed string as the label. However,
2767
2827
  especially in the case of a group footer, you might want a dynamically
2768
2828
  contructed label. You can use a proc or lambda for a label, and it will be
@@ -2796,6 +2856,7 @@ This would add the group's year to label, assuming the :date column of the
2796
2856
  footer's table had the same year for each item in the group.
2797
2857
 
2798
2858
  **** Aggregators
2859
+
2799
2860
  When adding a footer with the above methods, you can specify an aggregator for
2800
2861
  each column named in the ~agg_cols~ parameter. There are several candidates
2801
2862
  for what you can use for an aggregator:
@@ -2840,6 +2901,7 @@ for what you can use for an aggregator:
2840
2901
  itself.
2841
2902
 
2842
2903
  **** Footer objects
2904
+
2843
2905
  Each of the methods for adding a footer to a ~Formatter~ returns a ~Footer~ object
2844
2906
  that you can query for attributes of the generated footer, including accessing
2845
2907
  their computed values. Here are the accessors available on a
@@ -2862,6 +2924,7 @@ their computed values. Here are the accessors available on a
2862
2924
  ~k~ to specify which group to access in the case of a group footer.
2863
2925
 
2864
2926
  **** Footer Examples
2927
+
2865
2928
  As a reminder, here is the table, ~tab_a~ defined earlier:
2866
2929
 
2867
2930
  #+BEGIN_SRC ruby :wrap EXAMPLE
@@ -3116,6 +3179,7 @@ call one of the ~to_xxx~ methods directly on a table, which will yield a
3116
3179
  convenient way to do it. But there are a few other ways.
3117
3180
 
3118
3181
  **** By Instantiating a Formatter
3182
+
3119
3183
  You can instantiate a ~XXXFormatter~ object and feed it a table as a
3120
3184
  parameter. There is a Formatter subclass for each target output medium, for
3121
3185
  example, ~AoaFormatter~ will produce a ruby array of arrays. You can then call
@@ -3161,6 +3225,7 @@ you can call methods on it to affect the formatting of the output:
3161
3225
  #+END_EXAMPLE
3162
3226
 
3163
3227
  **** By Using ~FatTable~ module-level method calls
3228
+
3164
3229
  The ~FatTable~ module provides a set of methods of the form ~to_aoa~, ~to_text~,
3165
3230
  etc., to access a ~Formatter~ without having to create an instance yourself.
3166
3231
  Without a block, they apply the default formatting to the table and call the
@@ -3207,6 +3272,7 @@ automatically after the block:
3207
3272
  #+END_EXAMPLE
3208
3273
 
3209
3274
  **** By Calling Methods on Table Objects
3275
+
3210
3276
  Finally, as in many of the examples, you can call methods such as ~to_aoa~,
3211
3277
  ~to_text~, etc., directly on a Table:
3212
3278
 
data/fat_table.gemspec CHANGED
@@ -76,7 +76,6 @@ Gem::Specification.new do |spec|
76
76
  spec.add_development_dependency 'rubocop-performance'
77
77
  spec.add_development_dependency 'simplecov'
78
78
 
79
- spec.add_runtime_dependency 'activesupport', '>3.0'
80
79
  spec.add_runtime_dependency 'fat_core', '>= 4.9.0'
81
80
  spec.add_runtime_dependency 'rainbow'
82
81
  spec.add_runtime_dependency 'sequel'
@@ -173,7 +173,12 @@ module FatTable
173
173
  # Column. This makes Columns Enumerable, so all the Enumerable methods are
174
174
  # available on a Column.
175
175
  def each
176
- items.each { |itm| yield itm }
176
+ if block_given?
177
+ items.each { |itm| yield itm }
178
+ self
179
+ else
180
+ to_enum(:each)
181
+ end
177
182
  end
178
183
 
179
184
  ##########################################################################
@@ -161,13 +161,22 @@ module FatTable
161
161
  def self.convert_to_numeric(val)
162
162
  return BigDecimal(val, Float::DIG) if val.is_a?(Float)
163
163
  return val if val.is_a?(Numeric)
164
+
164
165
  # Eliminate any commas, $'s (or other currency symbol), or _'s.
165
166
  cursym = Regexp.quote(FatTable.currency_symbol)
166
167
  clean_re = /[,_#{cursym}]/
167
168
  val = val.to_s.clean.gsub(clean_re, '')
168
169
  return nil if val.blank?
170
+
169
171
  case val
170
- when /(\A[-+]?\d+\.\d*\z)|(\A[-+]?\d*\.\d+\z)/
172
+ when /\A[-+]?\d+\.\z/
173
+ # Catch quirk in Ruby's BigDecimal converter where a number ending in
174
+ # a decimal but with no digits after the decimal throws an
175
+ # ArgumentError as an invalid value for BigDecimal(). Just append a
176
+ # '0'.
177
+ val += '0'
178
+ BigDecimal(val.to_s.clean)
179
+ when /(\A[-+]?\d+\.\d+\z)|(\A[-+]?\d*\.\d+\z)/
171
180
  BigDecimal(val.to_s.clean)
172
181
  when /\A[-+]?[\d]+\z/
173
182
  val.to_i
@@ -67,7 +67,7 @@ module FatTable
67
67
 
68
68
  # Return the value of the label, for the kth group if grouped.
69
69
  def label(k = 0)
70
- calc_label(k)
70
+ @values[@label_col][k]
71
71
  end
72
72
 
73
73
  # :category: Accessors
@@ -221,24 +221,32 @@ module FatTable
221
221
  @values[@label_col] << calc_label(k)
222
222
  end
223
223
  else
224
- @values[@label_col] = [calc_label(0)]
224
+ @values[@label_col] = [calc_label]
225
225
  end
226
226
  end
227
227
 
228
- # Calculate the label for the kth group, using k = 0 for non-group
228
+ # Calculate the label for the kth group, using k = nil for non-group
229
229
  # footers. If the label is a proc, call it with the group number.
230
- def calc_label(k)
230
+ def calc_label(k = nil)
231
231
  case @label
232
232
  when Proc
233
233
  case @label.arity
234
234
  when 0
235
235
  @label.call
236
236
  when 1
237
- @label.call(k)
237
+ k ? @label.call(k) : @label.call(self)
238
238
  when 2
239
- @label.call(k, self)
239
+ if k
240
+ @label.call(k, self)
241
+ else
242
+ raise ArgumentError, "a non-group footer label proc may only have 1 argument for the containing footer f"
243
+ end
240
244
  else
241
- raise ArgumentError, "footer label proc may only have 1 argument for group number k"
245
+ if k
246
+ raise ArgumentError, "group footer label proc may only have 0, 1, or 2 arguments for group number k and containing footer f"
247
+ else
248
+ raise ArgumentError, "a non-group footer label proc may only have 0 or 1 arguments for the containing footer f"
249
+ end
242
250
  end
243
251
  else
244
252
  @label.to_s
@@ -530,8 +530,13 @@ module FatTable
530
530
 
531
531
  # Yield each row of the table as a Hash with the column symbols as keys.
532
532
  def each
533
- rows.each do |row|
534
- yield row
533
+ if block_given?
534
+ rows.each do |row|
535
+ yield row
536
+ end
537
+ self
538
+ else
539
+ to_enum(:each)
535
540
  end
536
541
  end
537
542
 
@@ -947,20 +952,25 @@ module FatTable
947
952
  vars = old_row.merge(new_row)
948
953
  case expr
949
954
  when Symbol
950
- msg = "Column '#{expr}' in select does not exist"
955
+ msg = "select column '#{expr}' does not exist"
951
956
  raise UserError, msg unless vars.key?(expr)
952
957
 
953
958
  new_row[key] = vars[expr]
954
959
  when String
955
- new_row[key] = ev.evaluate(expr, locals: vars)
960
+ if expr.match?(/\A\s*:/)
961
+ # Leading colon signal a literal string
962
+ new_row[key] = expr.sub(/\A\s*:/, '')
963
+ else
964
+ # Otherwise, evaluate the string.
965
+ new_row[key] = ev.evaluate(expr, locals: vars)
966
+ end
967
+ when Numeric, DateTime, Date, TrueClass, FalseClass
968
+ new_row[key] = expr
956
969
  else
957
- msg = "Hash parameter '#{key}' to select must be a symbol or string"
970
+ msg = "select can't set column at '#{key}' to '#{expr}' of class #{expr.class}"
958
971
  raise UserError, msg
959
972
  end
960
973
  end
961
- # Set the group number and run the hook with the local variables set to
962
- # the row after the new row is evaluated.
963
- # vars = new_row.merge(__group: grp)
964
974
  ev.eval_after_hook(locals: new_row)
965
975
  result << new_row
966
976
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module FatTable
4
4
  # The current version of FatTable
5
- VERSION = '0.6.0'
5
+ VERSION = '0.6.3'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_table
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-26 00:00:00.000000000 Z
11
+ date: 2022-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -178,20 +178,6 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: activesupport
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">"
186
- - !ruby/object:Gem::Version
187
- version: '3.0'
188
- type: :runtime
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">"
193
- - !ruby/object:Gem::Version
194
- version: '3.0'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: fat_core
197
183
  requirement: !ruby/object:Gem::Requirement
@@ -287,6 +273,7 @@ files:
287
273
  - ".gitignore"
288
274
  - ".rspec"
289
275
  - ".rubocop.yml"
276
+ - ".simplecov"
290
277
  - ".travis.yml"
291
278
  - ".yardopts"
292
279
  - Gemfile