backports 1.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.
- data/LICENSE +20 -0
- data/README.rdoc +50 -0
- data/VERSION.yml +4 -0
- data/lib/backports.rb +15 -0
- data/lib/backports/enumerable.rb +62 -0
- data/lib/backports/fixnum.rb +11 -0
- data/lib/backports/hash.rb +26 -0
- data/lib/backports/module.rb +23 -0
- data/lib/backports/object.rb +22 -0
- data/lib/backports/string.rb +59 -0
- data/lib/backports/symbol.rb +6 -0
- data/test/backports_test.rb +65 -0
- data/test/test_helper.rb +10 -0
- metadata +74 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Marc-Andre Lafortune
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
= Backports Library
|
2
|
+
|
3
|
+
Essential backports that make it possible to use some of the really nice features of ruby 1.8.7, ruby 1.9 and rails from ruby 1.8.x
|
4
|
+
|
5
|
+
Conditions for inclusion:
|
6
|
+
1. Standard in either rails or ruby
|
7
|
+
2. Won't break older code
|
8
|
+
3. Simple and self-contained
|
9
|
+
|
10
|
+
The first and second rules avoids conflicts in future and the past respectively. Because of the second rule, incompatibilities between 1.8 and 1.9 methods are left alone.
|
11
|
+
For example, <tt>Module::instance_methods</tt> returns strings in 1.8 and symbols in 1.9; no change can be made without the risk of breaking existing code.
|
12
|
+
|
13
|
+
More complex features of activesupport (even things like String::pluralize), won't be included. <tt>require 'activesupport'</tt> if you need them!
|
14
|
+
|
15
|
+
I've added those as I need them; pull requests welcome (with tests for ruby 1.9 backports)
|
16
|
+
|
17
|
+
= List of backports
|
18
|
+
|
19
|
+
* Symbol
|
20
|
+
* +to_proc+ (e.g. <tt>foo.map(&:bar)</tt> )
|
21
|
+
* Kernel
|
22
|
+
* +require_relative+
|
23
|
+
* Module
|
24
|
+
* +alias_method_chain+
|
25
|
+
* Object
|
26
|
+
* +tap+, +returning+
|
27
|
+
* +try+
|
28
|
+
* String
|
29
|
+
* <tt>start_with?</tt>, <tt>end_with?</tt>
|
30
|
+
* +camelize+, +underscore+
|
31
|
+
* +dasherize+, +demodulize+
|
32
|
+
* +constantize+
|
33
|
+
* Hash
|
34
|
+
* <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt>
|
35
|
+
* +key+
|
36
|
+
* +symbolize_keys+, +symbolize_keys!+
|
37
|
+
* Enumerable
|
38
|
+
* +sum+
|
39
|
+
* +find_index+
|
40
|
+
* +take+, +take_while+, +drop+, +drop_while+
|
41
|
+
* +first+
|
42
|
+
* Fixnum
|
43
|
+
* <tt>odd?</tt>, <tt>even?</tt>
|
44
|
+
|
45
|
+
= License
|
46
|
+
|
47
|
+
+backports+ is released under the terms of the MIT License, see the included LICENSE file.
|
48
|
+
The code for backports was copied from rails when available.
|
49
|
+
|
50
|
+
Author:: Marc-André Lafortune
|
data/VERSION.yml
ADDED
data/lib/backports.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Kernel
|
2
|
+
# Standard in ruby 1.9.
|
3
|
+
def require_relative(relative_feature)
|
4
|
+
# Adapted from Pragmatic's "Programming Ruby" (since their version was buggy...)
|
5
|
+
file = caller.first.split(/:\d/,2).first
|
6
|
+
if /\A\((.*)\)/ =~ file # eval, etc.
|
7
|
+
raise LoadError, "require_relative is called in #{$1}"
|
8
|
+
end
|
9
|
+
require File.expand_path(relative_feature, File.dirname(file))
|
10
|
+
end unless method_defined? :require_relative
|
11
|
+
end
|
12
|
+
|
13
|
+
%w(object module enumerable string symbol fixnum hash).each do |lib|
|
14
|
+
require_relative "backports/#{lib}"
|
15
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Enumerable
|
2
|
+
# Standard in rails... See official documentation[http://api.rubyonrails.org/classes/Enumerable.html]
|
3
|
+
def sum(identity = 0, &block)
|
4
|
+
return identity unless size > 0
|
5
|
+
|
6
|
+
if block_given?
|
7
|
+
map(&block).sum
|
8
|
+
else
|
9
|
+
inject { |sum, element| sum + element }
|
10
|
+
end
|
11
|
+
end unless method_defined? :sum
|
12
|
+
|
13
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
14
|
+
def find_index(obj = nil)
|
15
|
+
return index(obj) unless block_given?
|
16
|
+
each_with_index do |element, i|
|
17
|
+
return i if yield(element)
|
18
|
+
end
|
19
|
+
nil
|
20
|
+
end unless method_defined? :find_index
|
21
|
+
|
22
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
23
|
+
def take(n)
|
24
|
+
returning([]) do |array|
|
25
|
+
each do |elem|
|
26
|
+
array << elem
|
27
|
+
break if array.size >= n
|
28
|
+
end unless n <= 0
|
29
|
+
end
|
30
|
+
end unless method_defined? :take
|
31
|
+
|
32
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
33
|
+
def take_while
|
34
|
+
raise NotImplemented unless block_given? #todo: what should this do?
|
35
|
+
inject([]) do |array, elem|
|
36
|
+
return array unless yield elem
|
37
|
+
array << elem
|
38
|
+
end
|
39
|
+
end unless method_defined? :take_while
|
40
|
+
|
41
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
42
|
+
def drop(n)
|
43
|
+
array = to_a
|
44
|
+
array[n...array.size] || []
|
45
|
+
end unless method_defined? :drop
|
46
|
+
|
47
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
48
|
+
def drop_while(&block)
|
49
|
+
raise NotImplemented unless block_given? #todo: what should this do?
|
50
|
+
array = to_a
|
51
|
+
array.each_with_index do |element, i|
|
52
|
+
return array.drop(i) unless yield(element)
|
53
|
+
end
|
54
|
+
[]
|
55
|
+
end unless method_defined? :drop_while
|
56
|
+
|
57
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
|
58
|
+
def first(*arg)
|
59
|
+
arg.empty? ? take(1)[0] : take(arg.first)
|
60
|
+
end unless method_defined? :first
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Fixnum
|
2
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
|
3
|
+
def odd?
|
4
|
+
self & 1 == 1
|
5
|
+
end unless method_defined? :odd?
|
6
|
+
|
7
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
|
8
|
+
def even?
|
9
|
+
self & 1 == 0
|
10
|
+
end unless method_defined? :even?
|
11
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Hash
|
2
|
+
# New ruby 1.9 constructor -- not documented?
|
3
|
+
# <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt>
|
4
|
+
class << self
|
5
|
+
alias_method :original_constructor, :[]
|
6
|
+
def [](*arg)
|
7
|
+
return original_constructor(*arg) unless arg.length == 1 && arg.first.is_a?(Array)
|
8
|
+
returning({}) do |h|
|
9
|
+
arg.first.each{|key, value| h[key] = value}
|
10
|
+
end
|
11
|
+
end unless (Hash[[[:test, :test]]] rescue false)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
|
15
|
+
def symbolize_keys
|
16
|
+
Hash[map{|key,value| [(key.to_sym rescue key) || key, value] }]
|
17
|
+
end unless method_defined? :symbolize_keys
|
18
|
+
|
19
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
|
20
|
+
def symbolize_keys!
|
21
|
+
self.replace(self.symbolize_keys)
|
22
|
+
end unless method_defined? :symbolize_keys!
|
23
|
+
|
24
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Hash.html]
|
25
|
+
alias_method :key, :index unless method_defined? :key
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Module
|
2
|
+
# Standard in rails... See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Module.html]
|
3
|
+
def alias_method_chain(target, feature)
|
4
|
+
# Strip out punctuation on predicates or bang methods since
|
5
|
+
# e.g. target?_without_feature is not a valid method name.
|
6
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
7
|
+
yield(aliased_target, punctuation) if block_given?
|
8
|
+
|
9
|
+
with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
|
10
|
+
|
11
|
+
alias_method without_method, target
|
12
|
+
alias_method target, with_method
|
13
|
+
|
14
|
+
case
|
15
|
+
when public_method_defined?(without_method)
|
16
|
+
public target
|
17
|
+
when protected_method_defined?(without_method)
|
18
|
+
protected target
|
19
|
+
when private_method_defined?(without_method)
|
20
|
+
private target
|
21
|
+
end
|
22
|
+
end unless method_defined? :alias_method_chain
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/Object.html]
|
5
|
+
def try(method_id, *args, &block)
|
6
|
+
send(method_id, *args, &block) unless self.nil? #todo: check new def
|
7
|
+
end unless method_defined? :try
|
8
|
+
|
9
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Object.html]
|
10
|
+
def tap
|
11
|
+
yield self
|
12
|
+
self
|
13
|
+
end unless method_defined? :tap
|
14
|
+
|
15
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/Object.html]
|
16
|
+
def returning(obj)
|
17
|
+
yield obj
|
18
|
+
obj
|
19
|
+
end unless method_defined? :returning
|
20
|
+
|
21
|
+
Enumerator = Enumerable::Enumerator unless const_defined? :Enumerator # Standard in ruby 1.9
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class String
|
2
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
3
|
+
def start_with?(prefix)
|
4
|
+
prefix = prefix.to_s
|
5
|
+
self[0, prefix.length] == prefix
|
6
|
+
end unless method_defined? :start_with?
|
7
|
+
|
8
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
9
|
+
def end_with?(suffix)
|
10
|
+
suffix = suffix.to_s
|
11
|
+
self[-suffix.length, suffix.length] == suffix
|
12
|
+
end unless method_defined? :end_with?
|
13
|
+
|
14
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/String.html]
|
15
|
+
def getbyte(i)
|
16
|
+
self[i]
|
17
|
+
end unless method_defined? :getbyte
|
18
|
+
|
19
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
20
|
+
def camelize(first_letter = :upper)
|
21
|
+
if first_letter == :upper
|
22
|
+
gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
23
|
+
else
|
24
|
+
first.downcase + camelize[1..-1]
|
25
|
+
end
|
26
|
+
end unless method_defined? :camelize
|
27
|
+
|
28
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
29
|
+
def underscore(camel_cased_word)
|
30
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
31
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
32
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
33
|
+
tr("-", "_").
|
34
|
+
downcase
|
35
|
+
end unless method_defined? :underscore
|
36
|
+
|
37
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
38
|
+
def constantize(camel_cased_word)
|
39
|
+
names = camel_cased_word.split('::')
|
40
|
+
names.shift if names.empty? || names.first.empty?
|
41
|
+
|
42
|
+
constant = Object
|
43
|
+
names.each do |name|
|
44
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
45
|
+
end
|
46
|
+
constant
|
47
|
+
end unless method_defined? :constantize
|
48
|
+
|
49
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
50
|
+
def dasherize(underscored_word)
|
51
|
+
underscored_word.gsub(/_/, '-')
|
52
|
+
end unless method_defined? :dasherize
|
53
|
+
|
54
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
55
|
+
def demodulize(class_name_in_module)
|
56
|
+
class_name_in_module.to_s.gsub(/^.*::/, '')
|
57
|
+
end unless method_defined? :demodulize
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BackportsTest < Test::Unit::TestCase
|
4
|
+
context "find_index" do
|
5
|
+
should "conform to doc" do
|
6
|
+
assert_equal 3, %w{ant bat cat dog}.find_index {|item| item =~ /g/ }
|
7
|
+
assert_equal nil, %w{ant bat cat dog}.find_index {|item| item =~ /h/ }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "take" do
|
12
|
+
should "conform to doc" do
|
13
|
+
assert_equal [1, 2, 3], (1..7).take(3)
|
14
|
+
assert_equal [["a", 1], ["b", 2]], { 'a'=>1, 'b'=>2, 'c'=>3 }.take(2)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "only consume what's needed" do
|
18
|
+
assert_equal [], Enumerator.new(nil).take(0)
|
19
|
+
assert_raises(NoMethodError) { Enumerator.new(nil).take(1) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "take_while" do
|
24
|
+
should "conform to doc" do
|
25
|
+
assert_equal [1,2], (1..7).take_while {|item| item < 3 }
|
26
|
+
assert_equal [2,4,6], [ 2, 4, 6, 9, 11, 16 ].take_while(&:even?)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "work with infinite enumerables" do
|
30
|
+
assert_equal [1,2], (1..(1/0.0)).take_while {|item| item < 3 }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "drop" do
|
35
|
+
should "conform to doc" do
|
36
|
+
assert_equal [5, 8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop(4)
|
37
|
+
assert_equal [], [ 1, 1, 2, 3, 5, 8, 13 ].drop(99)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "work with enums" do
|
41
|
+
assert_equal [14,15], (10...16).drop(4)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "drop_while" do
|
46
|
+
should "conform to doc" do
|
47
|
+
assert_equal [8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop_while {|item| item < 6 }
|
48
|
+
end
|
49
|
+
|
50
|
+
should "work with enums" do
|
51
|
+
assert_equal [14,15], (10...16).drop_while {|item| item < 14}
|
52
|
+
end
|
53
|
+
|
54
|
+
should "work with extemity cases" do
|
55
|
+
assert_equal [10,11,12,13,14,15], (10...16).drop_while {|item| false}
|
56
|
+
assert_equal [], (10...16).drop_while {|item| true}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "Hash" do
|
61
|
+
should "should be constructible from key value pairs" do
|
62
|
+
assert_equal({1 => 2, 3 => 4}, Hash[[[1,2],[3,4]]])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: backports
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Marc-Andr\xC3\xA9 Lafortune"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-01 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Essential backports that enable some of the really nice features of ruby 1.8.7, ruby 1.9 and rails from ruby 1.8.6 and earlier.
|
17
|
+
email: github@marc-andre.ca
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- LICENSE
|
25
|
+
files:
|
26
|
+
- README.rdoc
|
27
|
+
- VERSION.yml
|
28
|
+
- lib/backports
|
29
|
+
- lib/backports/enumerable.rb
|
30
|
+
- lib/backports/fixnum.rb
|
31
|
+
- lib/backports/hash.rb
|
32
|
+
- lib/backports/module.rb
|
33
|
+
- lib/backports/object.rb
|
34
|
+
- lib/backports/string.rb
|
35
|
+
- lib/backports/symbol.rb
|
36
|
+
- lib/backports.rb
|
37
|
+
- test/backports_test.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
- LICENSE
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/marcandre/backports
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --title
|
45
|
+
- Backports library
|
46
|
+
- --main
|
47
|
+
- README.rdoc
|
48
|
+
- --line-numbers
|
49
|
+
- --inline-source
|
50
|
+
- --inline-source
|
51
|
+
- --charset=UTF-8
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project: marcandre
|
69
|
+
rubygems_version: 1.3.1
|
70
|
+
signing_key:
|
71
|
+
specification_version: 2
|
72
|
+
summary: Backports or ruby 1.8.7+ & rails for older ruby.
|
73
|
+
test_files: []
|
74
|
+
|