pax_global_header00006660000000000000000000000064117001014100014473gustar00rootroot0000000000000052 comment=9cbbe70e37124ed8a0aec000ca5f1b664b0d86b0 floehopper-instantiator-9cbbe70/000077500000000000000000000000001170010141000170505ustar00rootroot00000000000000floehopper-instantiator-9cbbe70/.gitignore000066400000000000000000000000411170010141000210330ustar00rootroot00000000000000*.gem .bundle Gemfile.lock pkg/* floehopper-instantiator-9cbbe70/.travis.yml000066400000000000000000000000301170010141000211520ustar00rootroot00000000000000rvm: - 1.8.6 - 1.8.7floehopper-instantiator-9cbbe70/COPYING.txt000066400000000000000000000020571170010141000207250ustar00rootroot00000000000000== Licence (MIT) Copyright (c) 2011 James Mead 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.floehopper-instantiator-9cbbe70/Gemfile000066400000000000000000000000461170010141000203430ustar00rootroot00000000000000source "http://rubygems.org" gemspec floehopper-instantiator-9cbbe70/README.md000066400000000000000000000007401170010141000203300ustar00rootroot00000000000000## Instantiator I want to be able to instantiate an arbitrary Ruby class without knowing anything about the constructor. The initial requirement for this has come from my [Introspection](https://github.com/floehopper/introspection) project. ### Usage class ArbitraryClass def initialize(arg1, arg2, *other_args) # stuff end end require "instantiator" instance = ArbitraryClass.instantiate p instance.class # => ArbitraryClassfloehopper-instantiator-9cbbe70/Rakefile000066400000000000000000000002751170010141000205210ustar00rootroot00000000000000require 'bundler/gem_tasks' require 'rake/testtask' task :default => :test Rake::TestTask.new do |t| t.libs << "test" t.test_files = FileList['test/*_test.rb'] t.verbose = true end floehopper-instantiator-9cbbe70/instantiator.gemspec000066400000000000000000000013101170010141000231270ustar00rootroot00000000000000# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "instantiator/version" Gem::Specification.new do |s| s.name = "instantiator" s.version = Instantiator::VERSION s.authors = ["James Mead"] s.email = ["james@floehopper.org"] s.homepage = "" s.summary = %q{Instantiate an arbitrary Ruby class} s.rubyforge_project = "instantiator" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.add_dependency("blankslate") s.add_development_dependency("rake") end floehopper-instantiator-9cbbe70/lib/000077500000000000000000000000001170010141000176165ustar00rootroot00000000000000floehopper-instantiator-9cbbe70/lib/instantiator.rb000066400000000000000000000040521170010141000226630ustar00rootroot00000000000000require "instantiator/version" require "instantiator/core_ext" require "blankslate" module Instantiator UNSUPPORTED_NAMESPACES = %w(Introspection OptionParser::Switch URI Net).freeze UNSUPPORTED_CLASSES = %w(Introspection OptionParser::Switch Gem::Installer Gem::Package::TarInput Zlib::GzipReader Zlib::GzipWriter Zlib::GzipFile Zlib::ZStream Bundler::Dependency Bundler::Definition Digest::Base Binding UnboundMethod Method Proc Process::Status Dir File::Stat MatchData Struct Bignum Float Fixnum Integer Continuation Thread NameError::message SignalException FalseClass TrueClass Data Symbol NilClass Socket UNIXServer UNIXSocket TCPServer TCPSocket UDPSocket IPSocket BasicSocket Trying).freeze UNSUPPORTED_REGEX = Regexp.new((UNSUPPORTED_NAMESPACES.map { |ns| "^#{ns}::" } + UNSUPPORTED_CLASSES.map { |c| "^#{c}$" }).join("|")).freeze def self.unsupported_class?(klass) klass.to_s[UNSUPPORTED_REGEX] end class Error < StandardError; end class MethodInvocationSink < ::BlankSlate def method_missing(method_name, *args, &block) MethodInvocationSink.new end def to_str String.new end def to_int Integer(0) end def to_ary Array.new end def to_hash Hash.new end end module ClassMethods def instantiate if Instantiator.unsupported_class?(self) raise Error.new("#{self}.instantiate is not yet supported") end if singleton_methods(false).map(&:to_sym).include?(:new) arity = method(:new).arity else arity = instance_method(:initialize).arity end numbers_of_parameters = arity >= 0 ? [arity] : (-(arity + 1)..5-(arity + 1)).to_a instance = nil numbers_of_parameters.each do |number_of_parameters| begin instance = new(*Array.new(number_of_parameters) { MethodInvocationSink.new }) return instance if instance rescue ArgumentError => e end end raise Error.new("Unable to instantiate #{self}") end end end class Class include Instantiator::ClassMethods end floehopper-instantiator-9cbbe70/lib/instantiator/000077500000000000000000000000001170010141000223355ustar00rootroot00000000000000floehopper-instantiator-9cbbe70/lib/instantiator/core_ext.rb000066400000000000000000000000461170010141000244720ustar00rootroot00000000000000require "instantiator/core_ext/symbol"floehopper-instantiator-9cbbe70/lib/instantiator/core_ext/000077500000000000000000000000001170010141000241455ustar00rootroot00000000000000floehopper-instantiator-9cbbe70/lib/instantiator/core_ext/symbol.rb000066400000000000000000000003571170010141000260040ustar00rootroot00000000000000class Symbol # Standard in ruby 1.8.7+. See official documentation[http://ruby-doc.org/core-1.9/classes/Symbol.html] def to_proc Proc.new { |*args| args.shift.__send__(self, *args) } end unless :to_proc.respond_to?(:to_proc) end floehopper-instantiator-9cbbe70/lib/instantiator/version.rb000066400000000000000000000000541170010141000243460ustar00rootroot00000000000000module Instantiator VERSION = "0.0.6" end floehopper-instantiator-9cbbe70/test/000077500000000000000000000000001170010141000200275ustar00rootroot00000000000000floehopper-instantiator-9cbbe70/test/instantiator_test.rb000066400000000000000000000135021170010141000241330ustar00rootroot00000000000000require "test_helper" require "instantiator" class InstantiatorTest < Test::Unit::TestCase def test_should_instantiate_class_with_no_explicit_initialize klass = Class.new instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_with_initialize_with_no_parameters klass = Class.new do def initialize; end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_with_initialize_with_one_parameter klass = Class.new do def initialize(parameter_one); end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_with_initialize_with_multiple_parameters klass = Class.new do def initialize(parameter_one, parameter_two, parameter_three, parameter_four); end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_with_initialize_with_only_optional_parameters klass = Class.new do def initialize(*optional_parameters); end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_with_initialize_with_some_required_parameters_and_some_optional_parameters klass = Class.new do def initialize(parameter_one, parameter_two, *optional_parameters); end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_calls_method_on_parameter klass = Class.new do def initialize(parameter_one) parameter_one.foo end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_calls_method_on_multiple_parameters klass = Class.new do def initialize(parameter_one, parameter_two, parameter_three, parameter_four) parameter_one.foo parameter_two.foo parameter_three.foo parameter_four.foo end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_calls_method_on_result_of_calling_method_on_parameter klass = Class.new do def initialize(parameter_one) parameter_one.foo.bar end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_with_no_parameters klass = Class.new do class << self alias_method :__new__, :new def new __new__("parameter_one") end end def initialize(parameter_one); end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_with_one_parameter klass = Class.new do class << self alias_method :__new__, :new def new(parameter_one) __new__ end end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_with_multiple_parameters klass = Class.new do class << self alias_method :__new__, :new def new(parameter_one, parameter_two, parameter_three, parameter_four) __new__ end end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_with_only_optional_parameters klass = Class.new do class << self alias_method :__new__, :new def new(*optional_parameters) __new__ end end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_with_some_required_parameters_and_some_optional_parameters klass = Class.new do class << self alias_method :__new__, :new def new(parameter_one, parameter_two, *optional_parameters) __new__ end end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_which_calls_method_on_parameter klass = Class.new do class << self alias_method :__new__, :new def new(parameter_one) parameter_one.foo __new__ end end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_which_calls_method_on_multiple_parameters klass = Class.new do class << self alias_method :__new__, :new def new(parameter_one, parameter_two, parameter_three, parameter_four) parameter_one.foo parameter_two.foo parameter_three.foo parameter_four.foo __new__ end end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_new_method_which_calls_method_on_result_of_calling_method_on_parameter klass = Class.new do class << self alias_method :__new__, :new def new(parameter_one) parameter_one.foo.bar __new__ end end end instance = klass.instantiate assert_equal klass, instance.class end def test_should_instantiate_class_which_defines_its_own_native_new_method_with_some_required_parameters_and_some_optional require "strscan" instance = StringScanner.instantiate end def test_should_raise_exception_if_instantiating_class_is_unsupported e = assert_raises(Instantiator::Error) { Proc.instantiate } assert_equal "Proc.instantiate is not yet supported", e.message end endfloehopper-instantiator-9cbbe70/test/method_invocation_sink_test.rb000066400000000000000000000010561170010141000261520ustar00rootroot00000000000000require "test_helper" require "instantiator" class MethodInvocationSinkTest < Test::Unit::TestCase include Instantiator def setup @sink = MethodInvocationSink.new end def test_should_return_instance_of_string assert_instance_of String, @sink.to_str end def test_should_return_instance_of_fixnum assert_instance_of Fixnum, @sink.to_int end def test_should_return_instance_of_array assert_instance_of Array, @sink.to_ary end def test_should_return_instance_of_hash assert_instance_of Hash, @sink.to_hash end endfloehopper-instantiator-9cbbe70/test/test_helper.rb000066400000000000000000000001401170010141000226650ustar00rootroot00000000000000require "rubygems" require "bundler" Bundler.setup(:default, :development) require "test/unit"