Skip to content

Commit

Permalink
Initial conversion to git.
Browse files Browse the repository at this point in the history
  • Loading branch information
djberg96 committed Jan 9, 2010
0 parents commit 0b59424
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 0 deletions.
27 changes: 27 additions & 0 deletions CHANGES
@@ -0,0 +1,27 @@
== 1.0.7 - 27-Sep-2009
* Fixed a packaging bug.
* Minor updates to the gemspec.
* Added the 'gem' Rakefile task.

== 1.0.6 - 26-Aug-2009
* Added the Hash#slice alias for Hash#[].
* Added the Hash#hash_of method that returns a sub-hash.
* Added test-unit 2.x as a development dependency.

== 1.0.5 - 30-Jul-2009
* Several updates to the gemspec, including a change in the license from
Artistic to Artistic 2.0.
* Added the install_gem Rake task, and other minor refactorings to the
Rakefile.
* Minor update to the test suite to make it Ruby 1.9.x compliant. The library
itself required no changes.

== 1.0.4 - 22-May-2008
* Library now managed by Daniel Berger with the kind permission of
the original author, Michael Granger.
* Added gemspec, README, MANIFEST, and CHANGES files.
* Added a Rakefile with tasks for testing and installation.
* Replaced the test suite with one based on Test::Unit.

== 1.0.3 - 9-Jun-2004
* Last release by Michael Granger
7 changes: 7 additions & 0 deletions MANIFEST
@@ -0,0 +1,7 @@
* CHANGES
* MANIFEST
* README
* Rakefile
* hashslice.gemspec
* lib/hashslice.rb
* test/test_hashslice.rb
50 changes: 50 additions & 0 deletions README
@@ -0,0 +1,50 @@
= Description
Slicing for Ruby hashes.

= Installation
rake test (optional)
rake install

= Synopsis
require 'hashslice'

hash = {'a' => 1, 'b' => 2, 'c' => 3}

# Slice reference
hash['a', 'b'] # -> [1, 2]
hash['a'] # -> 1

# Slice assignment
hash['a', 'b'] = 7, 8

hash # -> {'a' => 7, 'b' => 8, 'c' => 3}

# Sub hash
hash.hash_of('a', 'b') # -> {'a' => 1, 'b' => 2}

= Overview
This library modifies the Hash#[] and Hash#[]= methods so that they can
handle list reference or assignment. It also adds the Hash#hash_of method
that returns a hash slice.

== Hash#[*keys]
If more than one key is provided then an array is returned. Single
keys work as before, i.e. they return a single value.

== Hash#[*keys]=(*values)
The values on the right are assigned to the keys on left on a one for one
If there are more values than keys, the extra values are dropped.

= Copyright
Copyright (c) 2001-2009, The FaerieMUD Consortium and Daniel J. Berger.
All rights reserved.

= License
This module is free software. You may use, modify, and/or redistribute this
software under the terms of the Artistic License 2.0

http://www.perlfoundation.org/artistic_license_2_0

= Authors
Michael Granger (original author)
Daniel Berger (current maintainer)
23 changes: 23 additions & 0 deletions Rakefile
@@ -0,0 +1,23 @@
require 'rake'
require 'rake/clean'
require 'rake/testtask'

desc "Install the hashslice library (non-gem)"
task :install do
cp 'lib/hashslice.rb', Config::CONFIG['sitelibdir'], :verbose => true
end

desc 'Build the hashslice gem'
task :gem do
spec = eval(IO.read('hashslice.gemspec'))
Gem::Builder.new(spec).buildend

desc "Install the hashslice library as a gem"
task :install_gem => [:gem] do
file = Dir["*.gem"].first
sh "gem install #{file}"end

Rake::TestTask.new do |t|
t.warning = true
t.verbose = true
end
Expand Down
25 changes: 25 additions & 0 deletions hashslice.gemspec
@@ -0,0 +1,25 @@
require 'rubygems'

Gem::Specification.new do |gem|
gem.name = 'hashslice'
gem.version = '1.0.7'
gem.authors = ['Daniel J. Berger', 'Michael Granger']
gem.license = 'Artistic 2.0'
gem.email = 'djberg96@gmail.com'
gem.homepage = 'http://www.rubyforge.org/projects/shards'
gem.summary = "Adds hash slicing to Ruby's Hash class"
gem.test_file = 'test/test_hashslice.rb'
gem.has_rdoc = true
gem.files = Dir['**/*'].reject{ |f| f.include?('CVS') }

gem.rubyforge_project = 'shards'
gem.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST']

gem.add_development_dependency('test-unit', '>= 2.0.3')

gem.description = <<-EOF
The hashslice library adds builtin hash slicing to Ruby's Hash class.
This lets you reference, or assign to, multiple hash keys simultaneously
via the Hash#[] and Hash#[]= methods, respectively.
EOF
end
65 changes: 65 additions & 0 deletions lib/hashslice.rb
@@ -0,0 +1,65 @@
class Hash
alias href []
alias hset []=

# The version of the hashslice library
VERSION_HASHSLICE = '1.0.7'

# Retrieve a hash slice. If a single key is provided, returns a single
# value. If multiple keys are provided, an array of values is returned.
#
# Examples:
#
# hash = {'a' => 1, 'b' => 2, 'c' => 3}
# hash['a'] -> 1
# hash['a', 'c'] -> [1, 3]
#
def [](*args)
if args.length == 1
href(args[0])
else
args.map{ |k| href(k) }
end
end

alias slice []

# Hash slice assignment. You can assign a list of values to a list of keys
# in a single operation on a one for one basis.
#
# If the number of keys exceeds the number of values, the remaining keys
# are assigned a value of nil.
#
# If the number of values exceeds the number of keys, the extra values are
# dropped.
#
# Examples:
#
# hash['a'] = 1, 2 -> {a => [1, 2]}
# hash['a', 'b'] = 3, 4 -> {a => 3, b => 4}
# hash['a', 'b'] = 5 -> {a => 5, b => nil}
# hash['a', 'b'] = 3, 4, 5 -> {a => 3, b => 4}
#
def []=(*args)
if args.length <= 2
hset(*args)
else
values = args.pop # Last arg is the value. The rest are keys.
values = [values] unless values.is_a?(Array)
args.each_index{ |i| hset(args[i], values[i]) }
end
end

# Returns a sub-hash of the current hash.
#
# Example:
#
# hash = {'a' => 1, 'b' => 2, 'c' => 3}
# hash.hash_of('a', 'b') -> {'a' => 1, 'b' => 2}
#
def hash_of(*args)
temp = {}
args.map{ |k| temp[k] = href(k) }
temp
end
end
95 changes: 95 additions & 0 deletions test/test_hashslice.rb
@@ -0,0 +1,95 @@
#######################################################################
# test_hashslice.rb
#
# Test suite for the hashslice library. You should run these tests
# via the 'rake test' task.
#######################################################################
require 'rubygems'
gem 'test-unit'

require 'hashslice'
require 'test/unit'

class TC_Hashslice < Test::Unit::TestCase
def setup
@hash = {'a' => 1, 'b' => 2}
end

def test_version
assert_equal('1.0.7', Hash::VERSION_HASHSLICE)
end

def test_get_slice_instance_method_basic
assert_respond_to(@hash, :[])
assert_nothing_raised{ @hash['a'] }
assert_nothing_raised{ @hash['a', 'b'] }
assert_kind_of(Integer, @hash['a'])
assert_kind_of(Array, @hash['a', 'b'])
end

def test_get_slice_instance_method
assert_equal(1, @hash['a'])
assert_equal([1, 2], @hash['a', 'b'])
assert_equal([1, 2, nil], @hash['a', 'b', 'c'])
assert_nil(@hash['bogus'])
end

def test_get_slice_duplicate_keys
assert_equal([1, 1], @hash['a', 'a'])
assert_equal([1, 2, 1, 2], @hash['a', 'b', 'a', 'b'])
end

def test_set_slice_instance_method_basic
assert_respond_to(@hash, :[]=)
assert_nothing_raised{ @hash['a'] = 3 }
assert_nothing_raised{ @hash['a', 'b'] = 3 }
assert_nothing_raised{ @hash['a', 'b'] = 3, 4 }
assert_kind_of(Fixnum, @hash['a'] = 3)
assert_kind_of(Fixnum, @hash['a', 'b'] = 3)
assert_kind_of(Fixnum, @hash['a', 'b'] = 3, 4)
end

# hash[key] = value
def test_set_slice_instance_method_single_key_and_value
assert_nothing_raised{ @hash['a'] = 3 }
assert_nothing_raised{ @hash['b'] = [1, 2] }
assert_equal({'a' => 3, 'b' => [1, 2]}, @hash)
end

# hash[key1, key2] = value
def test_set_slice_instance_method_multiple_keys_single_value
assert_nothing_raised{ @hash['a', 'b'] = 3 }
assert_equal({'a' => 3, 'b' => nil}, @hash)
end

# hash[key1, key2] = value1, value2
def test_set_slice_instance_method_multiple_keys_multiple_values
assert_nothing_raised{ @hash['a', 'b'] = 3, 4 }
assert_equal({'a' => 3, 'b' => 4}, @hash)
end

# hash[key] = value1, value2
def test_set_slice_instance_method_single_key_multiple_values
assert_nothing_raised{ @hash['a'] = 3, 4 }
assert_equal({'a' => [3, 4], 'b' => 2}, @hash)
end

# hash[key1, key2] = value1, value2, value3
def test_set_slice_instance_method_multiple_keys_odd_values
assert_nothing_raised{ @hash['a', 'b'] = 3, 4, 5 }
assert_equal({'a' => 3, 'b' => 4}, @hash)
end

def test_slice_alias
assert_true(Hash.instance_method(:slice) == Hash.instance_method(:[]))
end

def test_hash_of
assert_respond_to(@hash, :hash_of)
assert_equal({'a' => 1, 'b' => 2}, @hash.hash_of('a', 'b'))
end

def teardown
@hash = nil
end
end

0 comments on commit 0b59424

Please sign in to comment.