typed-array-0.1.2/0000755000175000017500000000000012067512261012031 5ustar daidaityped-array-0.1.2/metadata.yml0000644000175000017500000000603212067512261014335 0ustar daidai--- !ruby/object:Gem::Specification name: typed-array version: !ruby/object:Gem::Version prerelease: version: 0.1.2 platform: ruby authors: - Ryan Biesemeyer autorequire: bindir: bin cert_chain: [] date: 2011-08-03 00:00:00 Z dependencies: - !ruby/object:Gem::Dependency name: rspec requirement: &id001 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 2.3.0 type: :development prerelease: false version_requirements: *id001 - !ruby/object:Gem::Dependency name: bundler requirement: &id002 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 1.0.0 type: :development prerelease: false version_requirements: *id002 - !ruby/object:Gem::Dependency name: jeweler requirement: &id003 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 1.6.4 type: :development prerelease: false version_requirements: *id003 - !ruby/object:Gem::Dependency name: rcov requirement: &id004 !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version version: "0" type: :development prerelease: false version_requirements: *id004 description: " All methods that alter the contents of an array that implements this Gem are first checked to\n ensure that the added items are of the types allowed. All methods behave exactly as their Array\n counterparts, including additional forms, block processing, etc.\n\n Defining a TypedArray Class:\n\n ```ruby\n class ThingsArray < Array\n extend TypedArray\n restrict_types Thing1, Thing2\n end\n\n things = ThingsArray.new\n ```\n\n Generating a single TypedArray\n \n ```ruby\n things = TypedArray(Thing1,Thing2).new\n\n These classes can be extended, and their accepted-types appended to after their initial definition.\n" email: ruby-dev@yaauie.com executables: [] extensions: [] extra_rdoc_files: - LICENSE.txt - README.rdoc files: - .document - .rspec - Gemfile - Gemfile.lock - LICENSE.txt - README.rdoc - Rakefile - VERSION - lib/typed-array.rb - lib/typed-array/.DS_Store - lib/typed-array/functions.rb - spec/spec_helper.rb - spec/typed-array_spec.rb - typed-array.gemspec homepage: http://github.com/yaauie/typed-array licenses: - MIT post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 2753660141613797258 segments: - 0 version: "0" required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version version: "0" requirements: [] rubyforge_project: rubygems_version: 1.8.6 signing_key: specification_version: 3 summary: Provides methods for creating type-enforced Arrays test_files: [] typed-array-0.1.2/typed-array.gemspec0000644000175000017500000000477112067512261015650 0ustar daidai# Generated by jeweler # DO NOT EDIT THIS FILE DIRECTLY # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- Gem::Specification.new do |s| s.name = %q{typed-array} s.version = "0.1.2" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = [%q{Ryan Biesemeyer}] s.date = %q{2011-08-03} s.description = %q{ All methods that alter the contents of an array that implements this Gem are first checked to ensure that the added items are of the types allowed. All methods behave exactly as their Array counterparts, including additional forms, block processing, etc. Defining a TypedArray Class: ```ruby class ThingsArray < Array extend TypedArray restrict_types Thing1, Thing2 end things = ThingsArray.new ``` Generating a single TypedArray ```ruby things = TypedArray(Thing1,Thing2).new These classes can be extended, and their accepted-types appended to after their initial definition. } s.email = %q{ruby-dev@yaauie.com} s.extra_rdoc_files = [ "LICENSE.txt", "README.rdoc" ] s.files = [ ".document", ".rspec", "Gemfile", "Gemfile.lock", "LICENSE.txt", "README.rdoc", "Rakefile", "VERSION", "lib/typed-array.rb", "lib/typed-array/.DS_Store", "lib/typed-array/functions.rb", "spec/spec_helper.rb", "spec/typed-array_spec.rb", "typed-array.gemspec" ] s.homepage = %q{http://github.com/yaauie/typed-array} s.licenses = [%q{MIT}] s.require_paths = [%q{lib}] s.rubygems_version = %q{1.8.6} s.summary = %q{Provides methods for creating type-enforced Arrays} if s.respond_to? :specification_version then s.specification_version = 3 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, ["~> 2.3.0"]) s.add_development_dependency(%q, ["~> 1.0.0"]) s.add_development_dependency(%q, ["~> 1.6.4"]) s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, ["~> 2.3.0"]) s.add_dependency(%q, ["~> 1.0.0"]) s.add_dependency(%q, ["~> 1.6.4"]) s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, ["~> 2.3.0"]) s.add_dependency(%q, ["~> 1.0.0"]) s.add_dependency(%q, ["~> 1.6.4"]) s.add_dependency(%q, [">= 0"]) end end typed-array-0.1.2/spec/0000755000175000017500000000000012067512261012763 5ustar daidaityped-array-0.1.2/spec/typed-array_spec.rb0000644000175000017500000002232112067512261016563 0ustar daidairequire File.expand_path(File.dirname(__FILE__) + '/spec_helper') # We need to test in several different contexts, so provide the base info here. inputs = { [Symbol]=>{ :base => [:foo,:bar], :match => [:baz,:bingo], :fail => { :one => [:zip,0], :all => ['string',Class] } }, [Fixnum] => { :base => [ 1,2,3 ], :match => [ 17,18,19 ], :fail => { :one => [22,:symbol,43], :all => ['string',:symbol] } }, [String,Symbol] => { :base => ['Foo',:foo], :match => [:bar,'Bar'], :fail => { :one => [:yippee,'a stirng',17], :all => [12,Class,Array] } } } describe TypedArray do describe '#new' do inputs.each_pair do |accepted_types, config| context "when only accepting <#{accepted_types.inspect}>" do subject { TypedArray( *accepted_types ) } context 'Form 1: typed_ary.new()' do it "should have zero-length" do subject.new().length.should == 0 end it "should be empty" do subject.new().to_a.should be_empty end end context 'Form 1: typed_ary.new(size)' do it "should have the proper length" do subject.new(5).length.should == 5 end it "should conatin all nil values" do subject.new(5).to_a.should == [nil,nil,nil,nil,nil] end end context 'Form 2: typed_ary.new(size,object)' do it "should have the proper length" do subject.new(3,config[:match].first).length.should == 3 end it "should conatin the value specified" do subject.new(3,config[:match].first).to_a.should == [config[:match].first]*3 end it "should raise when obj is the wrong type" do expect{ subject.new( 3, config[:fail][:all].first ) }.to raise_error TypedArray::UnexpectedTypeException end end context 'Form 3: typed_ary.new( ary )' do it "should accept when all items match" do subject.new(config[:match]).to_a.should == config[:match] end it "should raise when one object is the wrong type" do expect{ subject.new(config[:fail][:one])}.to raise_error TypedArray::UnexpectedTypeException end it "should raise when more than one object is the wrong type" do expect{ subject.new(config[:fail][:all])}.to raise_error TypedArray::UnexpectedTypeException end end context 'Form 4: typed_ary.new(size){|index|block}' do it "should populate when block returns the right type" do subject.new(config[:match].length){|i| config[:match][i]}.to_a.should == config[:match] end it "should raise when block returns wrong type once" do expect{ subject.new(config[:fail][:one].length){|i| config[:fail][:one][i]} }.to raise_error TypedArray::UnexpectedTypeException end it "should raise when block returns wrong type more than once" do expect{ subject.new(config[:fail][:all].length){|i| config[:fail][:all][i]} }.to raise_error TypedArray::UnexpectedTypeException end end end end end [:<<,:unshift,:push].each do |method| context %Q{typed_ary#{('a'..'z').include?(method.to_s[0]) ? '.' : ' '}#{method.to_s} other_ary} do inputs.each_pair do |accepted_types,config| context "when only accepting <#{accepted_types.inspect}>" do before :each do @typed_ary = TypedArray( *accepted_types).new(config[:base]) @ary = config[:base].to_a end context "when the item being pushed matches (#{config[:match].first})" do before :each do @item = config[:match].first end it "should return as Array would return" do @typed_ary.send(method,@item).to_a.should == @ary.send(method,@item) end it "should modify the TypedArray as Array would be modified" do @typed_ary.send(method,@item) @ary.send(method,@item) @typed_ary.to_a.should == @ary end end context "when the item being pushed does not match (#{config[:fail][:all].first})" do before :each do @item = config[:fail][:all].first end it "should raise an exception" do expect{ @typed_ary.send(method,@item) }.to raise_error TypedArray::UnexpectedTypeException end it "should not modify typed_ary" do begin backup = @typed_ary.to_a @typed_ary.send(method,@item) rescue TypedArray::UnexpectedTypeException ensure @typed_ary.to_a.should == backup end end end end end end end [:[]=].each do |method| context %Q{typed_ary[idx]= other_ary} do inputs.each_pair do |accepted_types,config| context "when only accepting <#{accepted_types.inspect}>" do before :each do @typed_ary = TypedArray( *accepted_types).new(config[:base]) @ary = config[:base].to_a end context "when the item being pushed matches (#{config[:match].first})" do before :each do @item = config[:match].first end it "should return as Array would return" do @typed_ary.send(method,4,@item).should == @ary.send(method,4,@item) end it "should modify the TypedArray as Array would be modified" do @typed_ary.send(method,4,@item) @ary.send(method,4,@item) @typed_ary.to_a.should == @ary end end context "when the item being pushed does not match (#{config[:fail][:all].first})" do before :each do @item = config[:fail][:all].first end it "should raise an exception" do expect{ @typed_ary.send(method,4,@item) }.to raise_error TypedArray::UnexpectedTypeException end it "should not modify typed_ary" do begin backup = @typed_ary.to_a @typed_ary.send(method,4,@item) rescue TypedArray::UnexpectedTypeException ensure @typed_ary.to_a.should == backup end end end end end end end [:+,:&,:concat,:replace].each do |method| context %Q{typed_ary#{('a'..'z').include?(method.to_s[0]) ? '.' : ' '}#{method.to_s} other_ary} do inputs.each_pair do |accepted_types,config| context "when only accepting <#{accepted_types.inspect}>" do before :each do @typed_ary = TypedArray( *accepted_types).new(config[:base]) @ary = config[:base].to_a end context "when all items match (#{config[:match].inspect})" do before :each do @other_ary = config[:match].to_a end it "should return as Array would return" do @typed_ary.send(method,@other_ary).to_a.should == @ary.send(method,@other_ary) end it "should modify the TypedArray as Array would be modified" do @typed_ary.send(method,@other_ary) @ary.send(method,@other_ary) @typed_ary.to_a.should == @ary end end config[:fail].each_key do |fail_type| context "when #{fail_type} item fails to match (#{config[:fail][fail_type].inspect})" do before :each do @other_ary = config[:fail][fail_type].to_a end unless method == :& # `and` opperator cannot produce elements that are not in both arrays already; since one is assuredly filtered, we can skip this. it "should raise an exception" do expect{ @typed_ary.send(method,@other_ary) }.to raise_error TypedArray::UnexpectedTypeException end end it "should not modify the TypedArray" do begin backup = @typed_ary.to_a @typed_ary.send(method,@other_ary) rescue TypedArray::UnexpectedTypeException ensure @typed_ary.to_a.should == backup end end end end end end end end context 'when extending classes' do before :each do @base = TypedArray(Symbol) @extension = Class.new( @base ) end it 'should inherit default restrictions' do @base.restricted_types.should == @extension.restricted_types end context 'when adding restricted_type to the parent' do it 'should propogate to the child' do @base.restricted_type Fixnum @extension.restricted_types.should include(Fixnum) end end context 'when adding restricted_type to the child' do it 'should not propogate to the parent' do @extension.restricted_type Fixnum @base.restricted_types.should_not include(Fixnum) end end end end typed-array-0.1.2/spec/spec_helper.rb0000644000175000017500000000055112067512261015602 0ustar daidai$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'rspec' require 'typed-array' # Requires supporting files with custom matchers and macros, etc, # in ./support/ and its subdirectories. Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} RSpec.configure do |config| end typed-array-0.1.2/lib/0000755000175000017500000000000012067512261012577 5ustar daidaityped-array-0.1.2/lib/typed-array/0000755000175000017500000000000012067512261015040 5ustar daidaityped-array-0.1.2/lib/typed-array/functions.rb0000644000175000017500000000522112067512261017375 0ustar daidai# Provides the validation functions that get included into a TypedArray # Namespace TypedArray module TypedArray # The functions that get included into TypedArray module Functions # Validates outcome. See Array#initialize def initialize *args, &block ary = Array.new *args, &block self.replace ary end # Validates outcome. See Array#replace def replace other_ary _ensure_all_items_in_array_are_allowed other_ary super end # Validates outcome. See Array#& def & ary self.class.new super end # Validates outcome. See Array#* def * int self.class.new super end # Validates outcome. See Array#+ def + ary self.class.new super end # Validates outcome. See Array#<< def << item _ensure_item_is_allowed item super end # Validates outcome. See Array#[] def [] idx self.class.new super end # Validates outcome. See Array#slice def slice *args self.class.new super end # Validates outcome. See Array#[]= def []= idx, item _ensure_item_is_allowed item super end # Validates outcome. See Array#concat def concat other_ary _ensure_all_items_in_array_are_allowed other_ary super end # Validates outcome. See Array#eql? def eql? other_ary _ensure_all_items_in_array_are_allowed other_ary super end # Validates outcome. See Array#fill def fill *args, &block ary = self.to_a ary.fill *args, &block self.replace ary end # Validates outcome. See Array#push def push *items _ensure_all_items_in_array_are_allowed items super end # Validates outcome. See Array#unshift def unshift *items _ensure_all_items_in_array_are_allowed items super end # Validates outcome. See Array#map! def map! &block self.replace( self.map &block ) end protected # Ensure that all items in the passed Array are allowed def _ensure_all_items_in_array_are_allowed ary # If we're getting an instance of self, accept return true if ary.is_a? self.class _ensure_item_is_allowed( ary, [Array] ) ary.each do |item| _ensure_item_is_allowed(item) end end # Ensure that the specific item passed is allowed def _ensure_item_is_allowed item, expected=nil return true if item.nil? #allow nil entries expected = self.class.restricted_types if expected.nil? expected.each do |allowed| return true if item.class <= allowed end raise TypedArray::UnexpectedTypeException.new expected, item.class end end endtyped-array-0.1.2/lib/typed-array/.DS_Store0000644000175000017500000001400412067512261016522 0ustar daidaiBud1%  @€ @€ @€ @ E%DSDB`€ @€ @€ @typed-array-0.1.2/lib/typed-array.rb0000644000175000017500000000427112067512261015371 0ustar daidai# :include: ../README.rdoc require "typed-array/functions" # Provides TypedArray functionality to a subclass of Array # when extended in the class's definiton module TypedArray # Hook the extension process in order to include the necessary functions # and do some basic sanity checks. def self.extended( mod ) unless mod <= Array raise UnexpectedTypeException.new( [Array], mod.class ) end mod.module_exec(self::Functions) do |functions_module| include functions_module end end # when a class inherits from this one, make sure that it also inherits # the types that are being enforced def inherited( subclass ) self._subclasses << subclass subclass.restricted_types *restricted_types end # A getter/setter for types to add. If no arguments are passed, it simply # returns the current array of accepted types. def restricted_types(*types) @_restricted_types ||= [] types.each do |type| raise UnexpectedTypeException.new([Class],type.class) unless type.is_a? Class @_restricted_types << type unless @_restricted_types.include? type _subclasses.each do |subclass| subclass.restricted_types type end end @_restricted_types end; alias :restricted_type :restricted_types # The exception that is raised when an Unexpected Type is reached during validation class UnexpectedTypeException < Exception # Provide access to the types of objects expected and the class of the object received attr_reader :expected, :received def initialize expected_one_of, received @expected = expected_one_of @received = received end def to_s %{Expected one of #{@expected.inspect} but received a(n) #{@received}} end end protected # a store of subclasses def _subclasses @_subclasses ||= [] end end # Provide a factory method. Takes any number of types to accept as arguments # and returns a class that behaves as a type-enforced array. def TypedArray *types_allowed klass = Class.new( Array ) klass.class_exec(types_allowed) do |types_allowed| extend TypedArray restricted_types *types_allowed restricted_types end klass.restricted_types klass end typed-array-0.1.2/VERSION0000644000175000017500000000000512067512261013074 0ustar daidai0.1.2typed-array-0.1.2/Rakefile0000644000175000017500000000372112067512261013501 0ustar daidai# encoding: utf-8 require 'rubygems' require 'bundler' begin Bundler.setup(:default, :development) rescue Bundler::BundlerError => e $stderr.puts e.message $stderr.puts "Run `bundle install` to install missing gems" exit e.status_code end require 'rake' require 'jeweler' Jeweler::Tasks.new do |gem| # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options gem.name = "typed-array" gem.homepage = "http://github.com/yaauie/typed-array" gem.license = "MIT" gem.summary = %Q{Provides methods for creating type-enforced Arrays} gem.description =<<-DESCRIPTION All methods that alter the contents of an array that implements this Gem are first checked to ensure that the added items are of the types allowed. All methods behave exactly as their Array counterparts, including additional forms, block processing, etc. Defining a TypedArray Class: ```ruby class ThingsArray < Array extend TypedArray restrict_types Thing1, Thing2 end things = ThingsArray.new ``` Generating a single TypedArray ```ruby things = TypedArray(Thing1,Thing2).new These classes can be extended, and their accepted-types appended to after their initial definition. DESCRIPTION gem.email = "ruby-dev@yaauie.com" gem.authors = ["Ryan Biesemeyer"] # dependencies defined in Gemfile end Jeweler::RubygemsDotOrgTasks.new require 'rspec/core' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |spec| spec.pattern = FileList['spec/**/*_spec.rb'] end RSpec::Core::RakeTask.new(:rcov) do |spec| spec.pattern = 'spec/**/*_spec.rb' spec.rcov = true end task :default => :spec require 'rake/rdoctask' Rake::RDocTask.new do |rdoc| version = File.exist?('VERSION') ? File.read('VERSION') : "" rdoc.rdoc_dir = 'rdoc' rdoc.title = "typed-array #{version}" rdoc.rdoc_files.include('README*') rdoc.rdoc_files.include('lib/**/*.rb') end typed-array-0.1.2/README.rdoc0000644000175000017500000000215412067512261013641 0ustar daidai= typed-array Gem provides enforced-type functionality to Arrays Copyright (c) 2011 Ryan Biesemeyer See LICENSE.txt for details Ryan Biesemeyer mailto:ruby-dev@yaauie.com == Example === Create Standard Class require 'typed-array' class Things < Array extend TypedArray restrict_types Thing1,Thing2 end === Generate Class using Factory require 'typed-array' things = TypedArray(Thing1,Thing2) === Adding items to the Array # All standard Array interfaces are implemented, including block-processing # and variable-number of arguments. For methods that would usually return an # Array, they instead return an instance of the current class (except to_a). # # The difference is that if the method would generate an Array including the # wrong types, TypedArray::UnexpectedTypeException is raised and the call is # aborted before modifying the enforced TypedArray instance. require 'typed-array' symbols = TypedArray(Symbol).new([:foo,:bar,:baz,:bingo]) begin integers = TypedArray(Integer).new([1,3,7,2,:symbol]) rescue TypedArray::UnexpectedTypeException puts "An error occured: #{$!}" end typed-array-0.1.2/LICENSE.txt0000644000175000017500000000204312067512261013653 0ustar daidaiCopyright (c) 2011 Ryan Biesemeyer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typed-array-0.1.2/Gemfile.lock0000644000175000017500000000077112067512261014260 0ustar daidaiGEM remote: http://rubygems.org/ specs: diff-lcs (1.1.2) git (1.2.5) jeweler (1.6.4) bundler (~> 1.0) git (>= 1.2.5) rake rake (0.9.2) rcov (0.9.9) rspec (2.3.0) rspec-core (~> 2.3.0) rspec-expectations (~> 2.3.0) rspec-mocks (~> 2.3.0) rspec-core (2.3.1) rspec-expectations (2.3.0) diff-lcs (~> 1.1.2) rspec-mocks (2.3.0) PLATFORMS ruby DEPENDENCIES bundler (~> 1.0.0) jeweler (~> 1.6.4) rcov rspec (~> 2.3.0) typed-array-0.1.2/Gemfile0000644000175000017500000000055412067512261013330 0ustar daidaisource "http://rubygems.org" # Add dependencies required to use your gem here. # Example: # gem "activesupport", ">= 2.3.5" # Add dependencies to develop your gem here. # Include everything needed to run rake, tests, features, etc. group :development do gem "rspec", "~> 2.3.0" gem "bundler", "~> 1.0.0" gem "jeweler", "~> 1.6.4" gem "rcov", ">= 0" end typed-array-0.1.2/.rspec0000644000175000017500000000001012067512261013135 0ustar daidai--color typed-array-0.1.2/.document0000644000175000017500000000006712067512261013653 0ustar daidailib/**/*.rb bin/* - features/**/*.feature LICENSE.txt