tickle 1.0.2 → 2.0.0rc3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2e7c98a6545c1b7e583d69309c0d76be4f91266c
4
- data.tar.gz: 0039b3ba223bf9082d7a290dd71b16395c5fe023
2
+ SHA256:
3
+ metadata.gz: 1f47be53e642fa9fd7cd412b7d76768807ed9398de11df69a77855f6d2b26b44
4
+ data.tar.gz: bc3a4d7d5c9048444ef7dfa47e6e55318c3e3577f7ec70145d4500bf441b5c4e
5
5
  SHA512:
6
- metadata.gz: a9dc27b51edc3cc4d3cd5d9df5dfbcbdbd6f249317a0bc3771238caa852fa079ed0f4873fd9bb1820f5bf0baabb535c0463b71c6b2cf52788d956661b46938ed
7
- data.tar.gz: 11697818c4cfa90fd2ee9fd539c34e3d8e813129e277effd4376a6c3179a9ead45a939eedb73fd6d44068ba05c724be333221d1ac073e53c16642f4b53fea238
6
+ metadata.gz: 6852b109c5091c3abee0bef6c8bf8ea804e9b2a7ff7b7ffd0d995b237f2dc799e3504ef10740a44e320dcd55544e1895e48235bbc745fde25394fc3b315f0121
7
+ data.tar.gz: 790b5b8790873c0e9a99c882cfe57628fd52ea756738e9c503ff76b38bd664b8ec469a6cc2fe313e823b26a498d6416f39d1986dda1236a3fa62c41c3dc057a3
data/.gitignore CHANGED
@@ -14,8 +14,10 @@ rdoc
14
14
  pkg
15
15
  bin/
16
16
  vendor/
17
+ vendor.noindex/
17
18
  Gemfile.lock
18
- spec/
19
19
  .yardoc/
20
20
  .bundle/
21
21
  .rspec
22
+ *.gem
23
+ .ruby-version
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.7
4
+ - jruby
5
+ - truffleruby
6
+
7
+ # whitelist
8
+ branches:
9
+ only:
10
+ - master
11
+ - develop
12
+ - v1-branch
data/CHANGES.md CHANGED
@@ -1,14 +1,36 @@
1
1
  # CH CH CH CH CHANGES! #
2
2
 
3
+ ## Friday the 18th of September 2002, v2.0.0rc3
3
4
 
4
- ## Monday the 11th of November, v1.0.2 ##
5
+ * Changed the dependency from chronic to gitlab-chronic, thanks to @bjonord
6
+
7
+ ----
8
+
9
+ ## v2.0.0.rc2, Friday the 8th of December 2017 ##
10
+
11
+ * Fixed issue #20 https://github.com/yb66/tickle/pull/20, thanks to [@antogon](https://github.com/antogon)
12
+
13
+ ----
14
+
15
+
16
+ ## Saturday the 7th of November 2015, 2.0.0.rc1 ##
17
+
18
+ * Rewrite of the internals.
19
+ * API should be pretty much the same from the outside, but enough things on the inside change to warrant the major version bump.
20
+ * Chronic updated to 0.10.2.
21
+
22
+ ----
23
+
24
+
25
+ ## Monday the 11th of November 2013, v1.0.2 ##
5
26
 
6
27
  * Shoulda and simplecov aren't runtime dependencies, fixed that in the gemfile.
7
28
  * Got the version number right this time ;-)
8
29
 
9
30
  ----
10
31
 
11
- ## Monday the 11th of November, v1.0.1 ##
32
+
33
+ ## Monday the 11th of November 2013, v1.0.1 ##
12
34
 
13
35
  * Moved library to new maintainer [https://github.com/yb66/tickle](@yb66)
14
36
  * Moved library to [http://semver.org/](semver).
@@ -19,4 +41,4 @@
19
41
  * Moved library to Bundler to make it easier to set up and develop against.
20
42
  * Started using Yardoc for more niceness with documentation.
21
43
 
22
- ----
44
+ ----
data/Gemfile CHANGED
@@ -2,7 +2,20 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "wirble"
5
+ group :development do
6
+ gem "maruku"
7
+ gem "yard"
8
+ unless RUBY_ENGINE == 'jruby'
9
+ gem "pry-byebug"
10
+ gem "pry-state"
11
+ gem "rb-readline"
12
+ end
13
+ end
14
+
6
15
  group :test do
7
16
  gem "rspec"
17
+ gem "rspec-its"
18
+ gem "timecop"
19
+ gem "simplecov"
20
+ gem "rake"
8
21
  end
data/LICENCE CHANGED
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2010 Joshua Lippiner
2
- Copyright (c) 2013 Iain Barnett
2
+ Copyright (c) 2015 Iain Barnett
3
3
 
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
data/README.md CHANGED
@@ -11,7 +11,7 @@ Take a look at the `develop` branch where all this stuff will be happening.
11
11
 
12
12
  Tickle is a natural language parser for recurring events.
13
13
 
14
- Tickle is designed to be a complement to [Chronic](https://rubygems.org/gems/chronic) and can interpret things such as "every 2 days, every Sunday, Sundays, Weekly, etc."
14
+ Tickle is designed to be a complement to [Chronic](https://rubygems.org/gems/chronic) and can interpret things such as "every 2 days", "every Sunday", Sundays", Weekly", etc.
15
15
 
16
16
  Tickle has one main method, `Tickle.parse`, which returns the next time the event should occur, at which point you simply call `Tickle.parse` again.
17
17
 
data/Rakefile CHANGED
@@ -1,13 +1,8 @@
1
- require 'rake/testtask'
2
- Rake::TestTask.new(:test) do |test|
3
- test.libs << 'lib' << 'test'
4
- test.pattern = 'test/**/test_*.rb'
5
- test.verbose = true
6
- end
1
+ require 'rspec/core/rake_task'
7
2
 
8
- task :test => :check_dependencies
3
+ RSpec::Core::RakeTask.new(:spec)
9
4
 
10
- task :default => :test
5
+ task :default => :spec
11
6
 
12
7
 
13
8
  desc "(Re-) generate documentation and place it in the docs/ dir. Open the index.html file in there to read it."
@@ -0,0 +1,71 @@
1
+ require 'benchmark'
2
+ require_relative "../lib/tickle.rb"
3
+ warn Benchmark.measure {
4
+ Tickle.parse('day')
5
+ # Tickle.parse('week')
6
+ Tickle.parse('month')
7
+ Tickle.parse('year')
8
+ Tickle.parse('daily')
9
+ # Tickle.parse('weekly')
10
+ Tickle.parse('monthly')
11
+ Tickle.parse('yearly')
12
+ Tickle.parse('3 days')
13
+ # Tickle.parse('3 weeks')
14
+ Tickle.parse('3 months')
15
+ Tickle.parse('3 years')
16
+ Tickle.parse('other day')
17
+ # Tickle.parse('other week')
18
+ Tickle.parse('other month')
19
+ Tickle.parse('other year')
20
+ Tickle.parse('Monday')
21
+ Tickle.parse('Wednesday')
22
+ Tickle.parse('Friday')
23
+ Tickle.parse('February', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
24
+ Tickle.parse('May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
25
+ Tickle.parse('june', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
26
+ Tickle.parse('beginning of the week')
27
+ Tickle.parse('middle of the week')
28
+ Tickle.parse('end of the week')
29
+ Tickle.parse('beginning of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
30
+ Tickle.parse('middle of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
31
+ Tickle.parse('end of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
32
+ Tickle.parse('beginning of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
33
+ Tickle.parse('middle of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
34
+ Tickle.parse('end of the year', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
35
+ Tickle.parse('the 3rd of May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
36
+ Tickle.parse('the 3rd of February', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
37
+ Tickle.parse('the 3rd of February 2022', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
38
+ Tickle.parse('the 3rd of Feb 2022', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
39
+ Tickle.parse('the 4th of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
40
+ Tickle.parse('the 10th of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
41
+ Tickle.parse('the tenth of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
42
+ Tickle.parse('first', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
43
+ Tickle.parse('the first of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
44
+ Tickle.parse('the thirtieth', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
45
+ Tickle.parse('the fifth', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
46
+ Tickle.parse('the 1st Wednesday of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
47
+ Tickle.parse('the 3rd Sunday of May', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
48
+ Tickle.parse('the 3rd Sunday of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
49
+ Tickle.parse('the 23rd of June', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
50
+ Tickle.parse('the twenty third of June', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
51
+ Tickle.parse('the thirty first of July', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
52
+ Tickle.parse('the twenty first', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
53
+ Tickle.parse('the twenty first of the month', {:start=>Time.parse("2020-04-01 00:00:00 +0000"), :now=>Time.parse("2020-04-01 00:00:00 +0000")})
54
+ Tickle.parse('starting today and ending one week from now')
55
+ Tickle.parse('starting tomorrow and ending one week from now')
56
+ Tickle.parse('starting Monday repeat every month')
57
+ Tickle.parse('starting May 13th repeat every week')
58
+ Tickle.parse('starting May 13th repeat every other day')
59
+ Tickle.parse('every other day starts May 13th')
60
+ Tickle.parse('every other day starts May 13')
61
+ Tickle.parse('every other day starting May 13th')
62
+ Tickle.parse('every other day starting May 13')
63
+ Tickle.parse('every week starts this wednesday')
64
+ Tickle.parse('every week starting this wednesday')
65
+ Tickle.parse('every other day starting May 1st 2021')
66
+ Tickle.parse('every other day starting May 1 2021')
67
+ Tickle.parse('every other week starting this Sunday')
68
+ Tickle.parse('every week starting this wednesday until May 13th')
69
+ Tickle.parse('every week starting this wednesday ends May 13th')
70
+ Tickle.parse('every week starting this wednesday ending May 13th')
71
+ }
@@ -0,0 +1,6 @@
1
+ class Array
2
+ # compares two arrays to determine if they both contain the same elements
3
+ def same?(y)
4
+ self.sort == y.sort
5
+ end
6
+ end
@@ -0,0 +1,64 @@
1
+ class Date
2
+ # returns the days in the sending month
3
+ def days_in_month
4
+ d,m,y = mday,month,year
5
+ d += 1 while Date.valid_civil?(y,m,d)
6
+ d - 1
7
+ end
8
+
9
+
10
+ # no idea what this is for
11
+ def bump(attr, amount=nil)
12
+ amount ||= 1
13
+ case attr
14
+ when :day then
15
+ Date.civil(self.year, self.month, self.day + amount)
16
+ when :wday then
17
+ amount = Date::ABBR_DAYNAMES.index(amount) if amount.is_a?(String)
18
+ raise Exception, "specified day of week invalid. Use #{Date::ABBR_DAYNAMES}" unless amount
19
+ diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
20
+ Date.civil(self.year, self.month, self.day + diff)
21
+ when :week then
22
+ Date.civil(self.year, self.month, self.day + (7*amount))
23
+ when :month then
24
+ Date.civil(self.year, self.month+amount, self.day)
25
+ when :year then
26
+ Date.civil(self.year + amount, self.month, self.day)
27
+ when :sec then
28
+ Date.civil(self.year, self.month, self.day, self.hour, self.minute, self.sec + amount)
29
+ else
30
+ raise Exception, "type \"#{attr}\" not supported."
31
+ end
32
+ end
33
+ end
34
+
35
+ class Time
36
+
37
+ # same again, no idea what this is for
38
+ def bump(attr, amount=nil)
39
+ amount ||= 1
40
+ case attr
41
+ when :sec then
42
+ Time.local(self.year, self.month, self.day, self.hour, self.min, self.sec + amount)
43
+ when :min then
44
+ Time.local(self.year, self.month, self.day, self.hour, self.min + amount, self.sec)
45
+ when :hour then
46
+ Time.local(self.year, self.month, self.day, self.hour + amount, self.min, self.sec)
47
+ when :day then
48
+ Time.local(self.year, self.month, self.day + amount, self.hour, self.min, self.sec)
49
+ when :wday then
50
+ amount = Time::RFC2822_DAY_NAME.index(amount) if amount.is_a?(String)
51
+ raise Exception, "specified day of week invalid. Use #{Time::RFC2822_DAY_NAME}" unless amount
52
+ diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
53
+ Time.local(self.year, self.month, self.day + diff, self.hour, self.min, self.sec)
54
+ when :week then
55
+ Time.local(self.year, self.month, self.day + (amount * 7), self.hour, self.min, self.sec)
56
+ when :month then
57
+ Time.local(self.year, self.month + amount, self.day, self.hour, self.min, self.sec)
58
+ when :year then
59
+ Time.local(self.year + amount, self.month, self.day, self.hour, self.min, self.sec)
60
+ else
61
+ raise Exception, "type \"#{attr}\" not supported."
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ module Tickle
2
+ class Ordinal < ::String
3
+ # returns true if the sending string is a text or numeric ordinal (e.g. first or 1st)
4
+ def is_ordinal?
5
+ scanner = %w{first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth nineteenth twenty thirty thirtieth}
6
+ regex = /\b(\d*)(st|nd|rd|th)\b/
7
+ !(self =~ regex).nil? || scanner.include?(self.downcase)
8
+ end
9
+
10
+ def ordinal_as_number
11
+ return self unless self.is_ordinal?
12
+ scanner = {/first/ => '1st',
13
+ /second/ => '2nd',
14
+ /third/ => '3rd',
15
+ /fourth/ => '4th',
16
+ /fifth/ => '5th',
17
+ /sixth/ => '6th',
18
+ /seventh/ => '7th',
19
+ /eighth/ => '8th',
20
+ /ninth/ => '9th',
21
+ /tenth/ => '10th',
22
+ /eleventh/ => '11th',
23
+ /twelfth/ => '12th',
24
+ /thirteenth/ => '13th',
25
+ /fourteenth/ => '14th',
26
+ /fifteenth/ => '15th',
27
+ /sixteenth/ => '16th',
28
+ /seventeenth/ => '17th',
29
+ /eighteenth/ => '18th',
30
+ /nineteenth/ => '19th',
31
+ /twentieth/ => '20th',
32
+ /thirtieth/ => '30th',
33
+ }
34
+ result = self
35
+ scanner.keys.each {|scanner_item| result = scanner[scanner_item] if scanner_item =~ self}
36
+ return result.gsub(/\b(\d*)(st|nd|rd|th)\b/, '\1')
37
+ end
38
+ end
39
+ end
@@ -7,26 +7,40 @@
7
7
  #=============================================================================
8
8
 
9
9
 
10
- $LOAD_PATH.unshift(File.dirname(__FILE__)) # For use/testing when no gem is installed
10
+ if ENV["DEBUG"]
11
+ warn "DEBUG MODE ON"
12
+ require 'pry-byebug'
13
+ require 'pry-state'
14
+ binding.pry
15
+ end
11
16
 
12
17
  require 'date'
13
18
  require 'time'
14
- require 'chronic'
19
+ require 'gitlab-chronic'
15
20
 
16
21
  require 'tickle/tickle'
17
22
  require 'tickle/handler'
18
23
  require 'tickle/repeater'
19
- require 'numerizer/numerizer'
24
+ require_relative "tickle/tickled.rb"
25
+ require_relative "ext/array.rb"
26
+ require_relative "ext/date_and_time.rb"
27
+ require_relative "ext/string.rb"
28
+
20
29
 
21
- module Tickle #:nodoc:
22
- VERSION = "0.1.7"
30
+ # Tickle is a natural language parser for recurring events.
31
+ module Tickle
23
32
 
24
- def self.debug=(val); @debug = val; end
33
+ def self.parse(asked, options = {})
34
+ # check to see if a datetime was passed
35
+ # if so, give it back
36
+ # TODO Consider converting to a Tickled
37
+ return asked if asked.respond_to? :day
25
38
 
26
- def self.dwrite(msg, line_feed=nil)
27
- (line_feed ? p(">> #{msg}") : puts(">> #{msg}")) if @debug
39
+ tickled = Tickled.new asked.dup, options
40
+ _parse tickled
28
41
  end
29
42
 
43
+
30
44
  def self.is_date(str)
31
45
  begin
32
46
  Date.parse(str.to_s)
@@ -35,108 +49,4 @@ module Tickle #:nodoc:
35
49
  return false
36
50
  end
37
51
  end
38
- end
39
-
40
- class Date #:nodoc:
41
- # returns the days in the sending month
42
- def days_in_month
43
- d,m,y = mday,month,year
44
- d += 1 while Date.valid_civil?(y,m,d)
45
- d - 1
46
- end
47
-
48
- def bump(attr, amount=nil)
49
- amount ||= 1
50
- case attr
51
- when :day then
52
- Date.civil(self.year, self.month, self.day + amount)
53
- when :wday then
54
- amount = Date::ABBR_DAYNAMES.index(amount) if amount.is_a?(String)
55
- raise Exception, "specified day of week invalid. Use #{Date::ABBR_DAYNAMES}" unless amount
56
- diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
57
- Date.civil(self.year, self.month, self.day + diff)
58
- when :week then
59
- Date.civil(self.year, self.month, self.day + (7*amount))
60
- when :month then
61
- Date.civil(self.year, self.month+amount, self.day)
62
- when :year then
63
- Date.civil(self.year + amount, self.month, self.day)
64
- else
65
- raise Exception, "type \"#{attr}\" not supported."
66
- end
67
- end
68
- end
69
-
70
- class Time #:nodoc:
71
- def bump(attr, amount=nil)
72
- amount ||= 1
73
- case attr
74
- when :sec then
75
- Time.local(self.year, self.month, self.day, self.hour, self.min, self.sec + amount)
76
- when :min then
77
- Time.local(self.year, self.month, self.day, self.hour, self.min + amount, self.sec)
78
- when :hour then
79
- Time.local(self.year, self.month, self.day, self.hour + amount, self.min, self.sec)
80
- when :day then
81
- Time.local(self.year, self.month, self.day + amount, self.hour, self.min, self.sec)
82
- when :wday then
83
- amount = Time::RFC2822_DAY_NAME.index(amount) if amount.is_a?(String)
84
- raise Exception, "specified day of week invalid. Use #{Time::RFC2822_DAY_NAME}" unless amount
85
- diff = (amount > self.wday) ? (amount - self.wday) : (7 - (self.wday - amount))
86
- Time.local(self.year, self.month, self.day + diff, self.hour, self.min, self.sec)
87
- when :week then
88
- Time.local(self.year, self.month, self.day + (amount * 7), self.hour, self.min, self.sec)
89
- when :month then
90
- Time.local(self.year, self.month + amount, self.day, self.hour, self.min, self.sec)
91
- when :year then
92
- Time.local(self.year + amount, self.month, self.day, self.hour, self.min, self.sec)
93
- else
94
- raise Exception, "type \"#{attr}\" not supported."
95
- end
96
- end
97
- end
98
-
99
- class String #:nodoc:
100
- # returns true if the sending string is a text or numeric ordinal (e.g. first or 1st)
101
- def is_ordinal?
102
- scanner = %w{first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth nineteenth twenty thirty thirtieth}
103
- regex = /\b(\d*)(st|nd|rd|th)\b/
104
- !(self =~ regex).nil? || scanner.include?(self.downcase)
105
- end
106
-
107
- def ordinal_as_number
108
- return self unless self.is_ordinal?
109
- scanner = {/first/ => '1st',
110
- /second/ => '2nd',
111
- /third/ => '3rd',
112
- /fourth/ => '4th',
113
- /fifth/ => '5th',
114
- /sixth/ => '6th',
115
- /seventh/ => '7th',
116
- /eighth/ => '8th',
117
- /ninth/ => '9th',
118
- /tenth/ => '10th',
119
- /eleventh/ => '11th',
120
- /twelfth/ => '12th',
121
- /thirteenth/ => '13th',
122
- /fourteenth/ => '14th',
123
- /fifteenth/ => '15th',
124
- /sixteenth/ => '16th',
125
- /seventeenth/ => '17th',
126
- /eighteenth/ => '18th',
127
- /nineteenth/ => '19th',
128
- /twentieth/ => '20th',
129
- /thirtieth/ => '30th',
130
- }
131
- result = self
132
- scanner.keys.each {|scanner_item| result = scanner[scanner_item] if scanner_item =~ self}
133
- return result.gsub(/\b(\d*)(st|nd|rd|th)\b/, '\1')
134
- end
135
- end
136
-
137
- class Array #:nodoc:
138
- # compares two arrays to determine if they both contain the same elements
139
- def same?(y)
140
- self.sort == y.sort
141
- end
142
- end
52
+ end