
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
[[https://travis-ci.org/ddoherty03/fat_core.svg?branch=master]]
fat-core is a simple gem to collect core extensions and a few new classes
that I find useful in multiple projects. The emphasis is on extending the
Date class to make it more useful in financial applications.
** Installation
Add this line to your application's Gemfile:
#+begin_SRC ruby gem 'fat_core', :git => 'https://github.com/ddoherty03/fat_core.git' #+end_SRC
And then execute:
#+begin_src shell $ bundle #+end_src
Or install it yourself as:
#+begin_src shell $ gem install fat_core #+end_src
** Usage
You can extend classes individually by requiring the corresponding file:
#+begin_SRC ruby require 'fat_core/array' require 'fat_core/bigdecimal' require 'fat_core/date' require 'fat_core/enumerable' require 'fat_core/hash' require 'fat_core/kernel' require 'fat_core/numeric' require 'fat_core/range' require 'fat_core/string' require 'fat_core/symbol' #+end_SRC
Or, you can require them all:
#+begin_SRC ruby require 'fat_core/all' #+end_SRC
Many of these have little that is of general interest, but there are a few goodies.
*** Date
**** Constants
FatCore adds two date constants to the Date class, Date::BOT and
Date::EOT. These represent the earliest and latest dates of practical
commercial interest. The exact values are rather arbitrary, but they prove
useful in date ranges, for example. They are defined as:
**** Ensure
The Date.ensure class method tries to convert its argument to a Date
object by (1) applying the #to_date method or (2) applying the Date.parse
method to a String. This is handy when you want to define a method that takes
a date argument but want the caller to be able to supply anything that can
reasonably be converted to a Date:
#+begin_src ruby $:.unshift("~/src/fat_core/lib") require 'fat_core/date' # => true
def tomorow_tomorrow(arg) from = Date.ensure(arg) # => ArgumentError: cannot convert class 'Array' to a Date or DateTime from + 2.days # => Mon, 03 Jun 2024, Wed, 16 Oct 2024 05:47:30 -0500, Sun, 03 Mar 2024 end # => :tomorow_tomorrow
tomorow_tomorrow('June 1') # => Mon, 03 Jun 2024 tomorow_tomorrow(Time.now) # => Wed, 16 Oct 2024 05:47:30 -0500
tomorow_tomorrow('Ides of March') # => Sun, 03 Mar 2024
tomorow_tomorrow([])
#+end_src
**** Formatting
FatCore provides some concise methods for printing string versions of dates
that are often useful:
#+begin_SRC ruby :results output :wrap example :exports both require 'fat_core/date' d = Date.parse('1957-09-22') puts "ISO: #{d.iso}" puts "All Numbers: #{d.num}" puts "Emacs Org Mode Inactive: #{d.org}" puts "Emacs Org Mode Active: #{d.org(true)}" puts "LaTeX: #{d.tex_quote}" puts "English: #{d.eng}" puts "American: #{d.american}" #+end_SRC
#+begin_example ISO: 1957-09-22 All Numbers: 19570922 Emacs Org Mode Inactive: [1957-09-22 Sun] Emacs Org Mode Active: <1957-09-22 Sun> LaTeX: 1957--09--22 English: September 22, 1957 American: 9/22/1957 #+end_example
Most of these are self-explanatory, but a couple are not. The #org method
formats a date as an Emacs org-mode timestamp, by default an inactive
timestamp that does not show up in the org agenda, but can be made active with
the optional parameter set to a truthy value. See
[[https://orgmode.org/manual/Timestamps.html#Timestamps]].
The #tex_quote method formats the date in iso form but using TeX's
convention of using en-dashes to separate the components.
**** Chunks
Many of the methods provided by FatCore deal with various calendar periods
that are less common than those provided by the Ruby Standard Library or gems
such as active_support. This documentation refers to these calendar periods
as "chunks", and they are the following:
FatCore provides methods that query whether the date falls on the beginning
or end of each of these chunks:
#+begin_SRC ruby :wrap example :exports both require 'fat_core/date'
tab = [] d = Date.parse('2017-06-30') %i[beginning end].each do |side| %i(year half quarter bimonth month semimonth biweek week).each do |chunk| meth = "#{side}of#{chunk}?".to_sym tab << [d.iso, meth.to_s, "#{d.send(meth)}"] end end tab #+end_SRC
#+RESULTS: #+begin_example | 2017-06-30 | beginning_of_year? | false | | 2017-06-30 | beginning_of_half? | false | | 2017-06-30 | beginning_of_quarter? | false | | 2017-06-30 | beginning_of_bimonth? | false | | 2017-06-30 | beginning_of_month? | false | | 2017-06-30 | beginning_of_semimonth? | false | | 2017-06-30 | beginning_of_biweek? | false | | 2017-06-30 | beginning_of_week? | false | | 2017-06-30 | end_of_year? | false | | 2017-06-30 | end_of_half? | true | | 2017-06-30 | end_of_quarter? | true | | 2017-06-30 | end_of_bimonth? | true | | 2017-06-30 | end_of_month? | true | | 2017-06-30 | end_of_semimonth? | true | | 2017-06-30 | end_of_biweek? | false | | 2017-06-30 | end_of_week? | false | #+end_example
It also provides corresponding methods that return the date at the beginning or end of the calendar chunk, starting at the given date:
#+begin_SRC ruby :wrap example :exports both require 'fat_core/date'
tab = [] d = Date.parse('2017-04-21') %i[beginning end].each do |side| %i(year half quarter bimonth month semimonth biweek week ).each do |chunk| meth = "#{side}of#{chunk}".to_sym tab << [d.iso, "d.#{meth}", "#{d.send(meth)}"] end end tab #+end_SRC
#+RESULTS: #+begin_example | 2017-04-21 | d.beginning_of_year | 2017-01-01 | | 2017-04-21 | d.beginning_of_half | 2017-01-01 | | 2017-04-21 | d.beginning_of_quarter | 2017-04-01 | | 2017-04-21 | d.beginning_of_bimonth | 2017-03-01 | | 2017-04-21 | d.beginning_of_month | 2017-04-01 | | 2017-04-21 | d.beginning_of_semimonth | 2017-04-16 | | 2017-04-21 | d.beginning_of_biweek | 2017-04-10 | | 2017-04-21 | d.beginning_of_week | 2017-04-17 | | 2017-04-21 | d.end_of_year | 2017-12-31 | | 2017-04-21 | d.end_of_half | 2017-06-30 | | 2017-04-21 | d.end_of_quarter | 2017-06-30 | | 2017-04-21 | d.end_of_bimonth | 2017-04-30 | | 2017-04-21 | d.end_of_month | 2017-04-30 | | 2017-04-21 | d.end_of_semimonth | 2017-04-30 | | 2017-04-21 | d.end_of_biweek | 2017-04-23 | | 2017-04-21 | d.end_of_week | 2017-04-23 | #+end_example
You can query which numerical half, quarter, etc. that a given date falls in:
#+begin_SRC ruby :exports both :wrap example require 'fat_core/date'
tab = [] %i(year half quarter bimonth month semimonth biweek week ).each do |chunk| d = Date.parse('2017-04-21') + rand(100) meth = "#{chunk}".to_sym tab << [d.iso, "d.#{meth}", "in #{chunk} number #{d.send(meth)}"] end tab #+end_SRC
#+RESULTS: #+begin_example | 2017-07-05 | d.year | in year number 2017 | | 2017-06-03 | d.half | in half number 1 | | 2017-05-30 | d.quarter | in quarter number 2 | | 2017-07-08 | d.bimonth | in bimonth number 4 | | 2017-06-28 | d.month | in month number 6 | | 2017-05-14 | d.semimonth | in semimonth number 9 | | 2017-07-25 | d.biweek | in biweek number 15 | | 2017-06-19 | d.week | in week number 25 | #+end_example
**** Parsing
FatCore also adds some convenience methods for parsing strings as Date
objects.
***** American Dates
Americans often write dates in the form M/d/Y, and the normal parse method
will parse such a string as d/M/Y, often resulting in invalid date errors.
FatCore adds the specialty parsing method, Date.parse_american to handle
such strings.
#+begin_SRC ruby :results output :exports both :wrap example require 'fat_core/date'
begin ss = '9/22/1957' Date.parse(ss) rescue Date::Error => ex puts "Date.parse('#{ss}') raises #{ex.class} (#{ex}), but" puts "Date.parse_american('#{ss}') => #{Date.parse_american(ss)}" end #+end_SRC
#+RESULTS: #+begin_example Date.parse('9/22/1957') raises Date::Error (invalid date), but Date.parse_american('9/22/1957') => 1957-09-22 #+end_example
***** Date Specs
It is often desirable to get the first or last date of a specified time
period. For this FatCore provides the parse_spec method that takes a
string and an optional spec_type parameter of either :from, indicating
that the first date of the period should be returned or :to, indicating that
the last date of the period should be returned.
This method supports a rich set of ways to specify periods of time:
Some things to note with respect to Date.parse_spec:
**** Holidays and Workdays
One of the original motivations for this library was to provide an easy way to
determine whether a given date is a federal holiday in the United States or,
nearly but not quite the same, a non-trading day on the New York Stock
Exchange. To that end, FatCore provides the following methods:
Methods concerning Federal holidays:
And we have similar methods for "holidays" or non-trading days on the NYSE:
**** Ordinal Weekdays in Month
It is often useful to find the 1st, 2nd, etc, Sunday, Monday, etc. in a given
month. FatCore provides the class method Date.nth_wday_in_year_month(nth,
wday, year, month) to return such dates. The first parameter can be
negative, which will count from the end of the month.
**** Easter
The Date class extension adds two methods for determining whether a given
date is a US federal holiday as defined by federal law, including such things
as federal holidays established by executive decree:
#+begin_SRC ruby require 'fat_core/date' Date.parse('2014-05-18').fed_holiday? => true # It's a weekend Date.parse('2014-01-01').fed_holiday? => true # It's New Years #+end_SRC
Likewise, days on which the NYSE is closed can be gotten with:
#+begin_SRC ruby Date.parse('2014-04-18').nyse_holiday? => true # It's Good Friday #+end_SRC
Conversely, Date#fed_workday? and Date#nyse_workday? return true if the
federal government and the NYSE respectively are open for business on those
days.
In addition, the Date class, as extended by FatCore, adds #next_
methods for calendar periods in addition to those provided by the core Date
class: #next_half, #next_quarter, #next_bimonth, and #next_semimonth,
#next_biweek. There are also #prior_ variants of these, as well as
methods for finding the end and beginning of all these periods (e.g.,
#beginning_of_bimonth) and for querying whether a Date is at the beginning or
end of these periods (e.g., #beginning_of_bimonth?, #end_of_bimonth?, etc.).
FatCore also provides convenience formatting methods, such as Date#iso for
quickly converting a Date to a string of the form 'YYYY-MM-DD', Date#org for
formatting a Date as an Emacs org-mode timestamp, and several others.
Finally, it provides a #parse_spec method for parsing a string, typically
provided by a user, allowing all the period chunks to be conveniently and
tersely specified by a user. For example, the string '2Q' will be parsed as the
second calendar quarter of the current year, while '2014-3Q' will be parsed as
the third quarter of the year 2014.
*** Range
You can also extend the Range class with several useful methods that emphasize
coverage of one range by one or more others (#spanned_by? and #gaps),
contiguity of Ranges to one another (#contiguous?, #left_contiguous?, and
#right_contiguous?, #join), and the testing of overlaps between ranges
(#overlaps?, #overlaps_among?). These are put to good use in the
'fat_period' ([[https://github.com/ddoherty03/fat_period]]) gem, which combines
fat_core's extended Range class with its extended Date class to make a useful
Period class for date ranges, and you may find fat_core's extended Range class
likewise useful.
For example, you can use the #gaps method to find the gaps left in the
coverage on one Range by an Array of other Ranges:
#+begin_SRC ruby require 'fat_core/range' (0..12).gaps([(0..2), (5..7), (10..12)]) => [(3..4), (8..9)] #+end_SRC
*** Hash
FatCore::Hash extends the Hash class with some useful methods for element
deletion (#delete_with_value) and for manipulating the keys
(#keys_with_value, #remap_keys and #replace_keys) of a Hash. It also
provides #each_pair_with_flags as an analog to Enumerable's
#each_with_flags.
It also provides the shovel operator as a convenient alias for Hash#merge,
so that
#+begin_src ruby :tangle no {a: 'A', b: 'B', c: 'C'} << {c: 'CC', d: 'DD'} << {e: 'EEE'} => {a: 'A', b: 'B', c: 'CC', d: 'DD', e: 'EEE'} #+end_src
*** String
FatCore::String has methods for performing matching of one string with another
(#matches_with, #fuzzy_match), for converting a string to title-case as
might by used in the title of a book (#entitle), for converting a String
into a useable Symbol (#as_sym) and vice-versa (#as_str also
Symbol#as_str), for wrapping with an optional hanging indent (#wrap),
cleaning up errant spaces (#clean), and computing the Damerau-Levenshtein
distance between strings (#distance). And several others.
*** TeX Quoting
Several of the extension, most notably 'fat_core/string', provides a
#tex_quote method for quoting the string version of an object so as to allow
its inclusion in a TeX document and quote characters such as '$' or '%' that
have a special meaning for TeX.
*** Numbers
FatCore::Numeric has methods for inserting grouping commas into a number
(#commas and #group), for converting seconds to HH:MM:SS.dd format
(#secs_to_hms), for testing for integrality (#whole? and #int_if_whole), and
testing for sign (#signum).
** Contributing
FAQs
Unknown package
We found that fat_core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.