backports 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|