kinda-core 0.0.2

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/README.rdoc ADDED
@@ -0,0 +1,14 @@
1
+ Author:: Manuel Vila (mailto:mvila@3base.com)
2
+ License:: Don't know yet
3
+
4
+ = Core
5
+
6
+ Basic helpers used by other kinda projects.
7
+
8
+ == Installation
9
+
10
+ $ sudo gem install kinda-core --source http://gems.github.com
11
+
12
+ == Usage
13
+
14
+ Still very alpha so documentation will come later.
@@ -0,0 +1,110 @@
1
+ module Kinda
2
+ module Core
3
+ module Accessor
4
+ module ClassMethods
5
+ # attr_reader(:name, :age, :size)
6
+ # attr_reader(:name => :@name) is the default behaviour but you can use:
7
+ # attr_reader (:name => @the_name) to use a different instance variable
8
+ # attr_reader(:name => :first_name) or even an another attribute.
9
+ # But more interesting, you can delegate to another object:
10
+ # attr_reader(:name => [:father, :name])
11
+ # attr_reader(:name => [:mother, :husband, :name])
12
+ def __attr_reader__(*attributes, with_filter, &block)
13
+ attributes.each do |attribute|
14
+ if attribute.is_a?(Hash)
15
+ attribute, source = attribute.first
16
+ else
17
+ source = "@#{attribute}"
18
+ end
19
+ proc = if with_filter || !block
20
+ ::Proc.new do |*args|
21
+ return send("#{attribute}=", *args) unless args.empty?
22
+ value = if source[0] == '@'
23
+ instance_variable_get(source)
24
+ else
25
+ [*source].inject(self) do |object, symbol|
26
+ object.send(symbol)
27
+ end
28
+ end
29
+ block ? instance_exec(value, &block) : value
30
+ end
31
+ else
32
+ block
33
+ end
34
+ to_class.send(:define_method, attribute, &proc)
35
+ end
36
+ end
37
+
38
+ def attr_reader(*attributes, &block)
39
+ __attr_reader__(*attributes, false, &block)
40
+ end
41
+
42
+ def attr_reader_with_filter(*attributes, &block)
43
+ __attr_reader__(*attributes, true, &block)
44
+ end
45
+
46
+ def __attr_writer__(*attributes, with_filter, &block)
47
+ attributes.each do |attribute|
48
+ if attribute.is_a?(Hash)
49
+ attribute, target = attribute.first
50
+ else
51
+ target = "@#{attribute}"
52
+ end
53
+ proc = if with_filter || !block
54
+ ::Proc.new do |value|
55
+ value = instance_exec(value, &block) if block
56
+ if target[0] == '@'
57
+ instance_variable_set(target, value)
58
+ else
59
+ [*target][0..-2].inject(self) do |object, symbol|
60
+ object.send(symbol)
61
+ end.send("#{[*target].last}=", value)
62
+ end
63
+ end
64
+ else
65
+ block
66
+ end
67
+ to_class.send(:define_method, "#{attribute}=", &proc)
68
+ end
69
+ end
70
+
71
+ def attr_writer(*attributes, &block)
72
+ __attr_writer__(*attributes, false, &block)
73
+ end
74
+
75
+ def attr_writer_with_filter(*attributes, &block)
76
+ __attr_writer__(*attributes, true, &block)
77
+ end
78
+
79
+ def attr_accessor(*attributes, &block)
80
+ attr_reader(*attributes, &block)
81
+ attr_writer(*attributes, &block)
82
+ end
83
+
84
+ def attr_accessor_with_filter(*attributes, &block)
85
+ attr_reader_with_filter(*attributes, &block)
86
+ attr_writer_with_filter(*attributes, &block)
87
+ end
88
+
89
+ def attr(attribute, writable=false)
90
+ attr_reader(attribute)
91
+ attr_writer(attribute) if writable
92
+ end
93
+
94
+ def attr_reader_with_default(attribute, default_value)
95
+ attr_reader_with_filter(attribute) do |value|
96
+ value.nil? ? default_value : value
97
+ end
98
+ end
99
+
100
+ def attr_accessor_with_default(attribute, default_value)
101
+ attr_reader_with_default(attribute, default_value)
102
+ attr_writer(attribute)
103
+ end
104
+ end
105
+
106
+ include ClassMethods
107
+ inheritable_extension ClassMethods
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,86 @@
1
+ require 'forwardable'
2
+
3
+ module Kinda
4
+ module Core
5
+ module Forwardable
6
+ module ClassMethods
7
+ include ::Forwardable
8
+
9
+ # Add a nice way to specify a different method for the accessor:
10
+ # delegate :remove => [:book, :delete]
11
+ # delegate [:add, :remove] => [:book, :<<, :delete]
12
+ def instance_delegate(hash)
13
+ hash.each do |delegate_methods, accessor|
14
+ accessor_methods = [*accessor]
15
+ accessor_object = accessor_methods.shift
16
+ [*delegate_methods].each do |delegate_method|
17
+ accessor_method = accessor_methods.shift || delegate_method
18
+ def_instance_delegator(accessor_object, accessor_method, delegate_method)
19
+ end
20
+ end
21
+ end
22
+
23
+ alias_method :delegate, :instance_delegate
24
+
25
+ # Create both reader and writer delegate
26
+ # Same usage than the simple "delegate" method except the following form
27
+ # in case the getter and setter symbols are different:
28
+ # delegate_attr :title => [:book, [:read_title, :write_title]]
29
+ def delegate_attr_accessor(hash, kind=(:accessor), with_filter=false, &block)
30
+ hash.each do |delegate_methods, accessor|
31
+ accessor_methods = [*accessor]
32
+ accessor_object = accessor_methods.shift
33
+ [*delegate_methods].each do |delegate_method|
34
+ accessor_method = accessor_methods.shift || delegate_method
35
+ accessor_getter, accessor_setter = case kind
36
+ when :accessor
37
+ getter, setter = [*accessor_method]
38
+ setter ||= getter
39
+ [getter, setter]
40
+ when :reader
41
+ [accessor_method, nil]
42
+ when :writer
43
+ [nil, accessor_method]
44
+ end
45
+ if accessor_getter
46
+ __attr_reader__({ delegate_method => [accessor_object, accessor_getter] },
47
+ with_filter, &block)
48
+ end
49
+ if accessor_setter
50
+ __attr_writer__({ delegate_method => [accessor_object, accessor_setter] },
51
+ with_filter, &block)
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ alias_method :delegate_attr, :delegate_attr_accessor
58
+
59
+ def delegate_attr_accessor_with_filter(hash, &block)
60
+ delegate_attr_accessor(hash, :accessor, true, &block)
61
+ end
62
+
63
+ alias_method :delegate_attr_with_filter, :delegate_attr_accessor_with_filter
64
+
65
+ def delegate_attr_reader(hash, &block)
66
+ delegate_attr_accessor(hash, :reader, false, &block)
67
+ end
68
+
69
+ def delegate_attr_reader_with_filter(hash, &block)
70
+ delegate_attr_accessor(hash, :reader, true, &block)
71
+ end
72
+
73
+ def delegate_attr_writer(hash, &block)
74
+ delegate_attr_accessor(hash, :writer, false, &block)
75
+ end
76
+
77
+ def delegate_attr_writer_with_filter(hash, &block)
78
+ delegate_attr_accessor(hash, :writer, true, &block)
79
+ end
80
+ end
81
+
82
+ include ClassMethods
83
+ inheritable_extension ClassMethods
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,19 @@
1
+ # Thomas Sawyer's Functor Class slightly modified for Ruby 1.9
2
+ # http://facets.rubyforge.org/apidoc/api/core/classes/Functor.html
3
+ module Kinda
4
+ module Core
5
+ class Functor < BasicObject
6
+ def initialize(&proc)
7
+ @proc = proc
8
+ end
9
+
10
+ def to_proc
11
+ @proc
12
+ end
13
+
14
+ def method_missing(method_name, *args, &block)
15
+ @proc.call(method_name, *args, &block)
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/core/hash.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Kinda
2
+ module Core
3
+ module Hash
4
+ def delete_value(value)
5
+ delete_if { |k, v| v == value }
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ class Hash
12
+ include Kinda::Core::Hash
13
+ end
@@ -0,0 +1,20 @@
1
+ module Kinda
2
+ module Core
3
+ def inspect(*args)
4
+ if %w[Bignum Class Complex Date DateTime FalseClass Fixnum Float
5
+ Integer NilClass Numeric Range Rational Regexp String Symbol
6
+ Time TrueClass].include?(self.class.name)
7
+ super()
8
+ else
9
+ result = '#<'
10
+ result += "#{self.class}:#{object_hexid}"
11
+ items = args.map do |arg|
12
+ "#{arg}=#{send(arg).inspect}" if respond_to?(arg)
13
+ end.compact
14
+ result += ' ' + items.join(', ') if !items.empty?
15
+ result += '>'
16
+ result
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,81 @@
1
+ module Kinda
2
+ module Core
3
+ module Module
4
+ def self.included(klass)
5
+ klass.alias_method_chain :append_features, :module_extensions
6
+ end
7
+
8
+ def alias_method_chain(target, feature)
9
+ # Strip out punctuation on predicates or bang methods since
10
+ # e.g. target?_without_feature is not a valid method name.
11
+ aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
12
+ yield(aliased_target, punctuation) if block_given?
13
+
14
+ with_method, without_method =
15
+ "#{aliased_target}_with_#{feature}#{punctuation}",
16
+ "#{aliased_target}_without_#{feature}#{punctuation}"
17
+
18
+ alias_method without_method, target
19
+ alias_method target, with_method
20
+
21
+ case
22
+ when public_method_defined?(without_method)
23
+ public target
24
+ when protected_method_defined?(without_method)
25
+ protected target
26
+ when private_method_defined?(without_method)
27
+ private target
28
+ end
29
+ end
30
+
31
+ def container
32
+ space = name[0...(name.rindex( '::' ) || 0)]
33
+ space.empty? ? Object : eval(space)
34
+ end
35
+
36
+ def extensions
37
+ singleton_class.ancestors.take_while { |mod| !mod.is_a?(Class) }
38
+ end
39
+
40
+ def inheritable_extension(*mods)
41
+ (@inheritable_extensions ||= []).unshift(mods.reverse).flatten!.uniq!
42
+ end
43
+
44
+ def append_features_with_module_extensions(target)
45
+ append_features_without_module_extensions(target)
46
+ if @inheritable_extensions
47
+ target.extend *@inheritable_extensions
48
+ target.inheritable_extension *@inheritable_extensions.reverse
49
+ end
50
+ end
51
+
52
+ def delegate_to_class(source, target=source)
53
+ define_method(source) do |*args, &block|
54
+ singleton_class_eval do
55
+ send(target, *args, &block)
56
+ end
57
+ end
58
+ end
59
+
60
+ def self_and_ancestors
61
+ result = ancestors
62
+ result.unshift self unless result.first == self
63
+ result
64
+ end
65
+
66
+ def ancestors_without_self
67
+ result = ancestors
68
+ result.first == self ? result.drop(1) : result
69
+ end
70
+
71
+ def ancestor
72
+ ancestors_without_self.first
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ class Module
79
+ include Kinda::Core::Module
80
+ end
81
+
@@ -0,0 +1,63 @@
1
+ module Kinda
2
+ module Core
3
+ module Object
4
+ def self.included(klass)
5
+ klass.alias_method_chain :extend, :flexible_arguments
6
+ end
7
+
8
+ def object_hexid
9
+ "0x" + ('%.x' % (self.__id__ * 2))
10
+ end
11
+
12
+ def singleton_class
13
+ class << self; self; end
14
+ end
15
+
16
+ def singleton_class_eval(&block)
17
+ singleton_class.class_eval(&block)
18
+ end
19
+
20
+ def to_class
21
+ kind_of?(Module) ? self : singleton_class
22
+ end
23
+
24
+ alias_method :to_module, :to_class
25
+
26
+ def extend_with_flexible_arguments(*modules)
27
+ mods = modules.flatten
28
+ extend_without_flexible_arguments(*mods) unless mods.empty?
29
+ end
30
+
31
+ def tap
32
+ return super if block_given?
33
+ Functor.new { |method, *args| self.send(method, *args); self }
34
+ end
35
+
36
+ def try(methods, *args, &block)
37
+ methods = [*methods].dup
38
+ return self if methods.empty?
39
+ send(methods.shift, *args, &block).try(methods, *args, &block) if
40
+ respond_to?(methods.first)
41
+ end
42
+
43
+ def receiver
44
+ self
45
+ end
46
+
47
+ alias_method :__instance_exec__, :instance_exec
48
+
49
+ def parse_arguments(args, *defaults)
50
+ args = args.dup
51
+ options = args.last.is_a?(Hash) ? args.pop : {}
52
+ raise ArgumentError, "Too many arguments (#{args.size} for #{defaults.size})" if
53
+ args.size > defaults.size
54
+ defaults.drop(args.size).each { |default| args << default }
55
+ args << options
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ class Object
62
+ include Kinda::Core::Object
63
+ end
data/lib/core/proc.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Kinda
2
+ module Core
3
+ module Proc
4
+ def call_with_this(this, *args, &block)
5
+ binding_self = binding.eval('self')
6
+ binding_self.push_this(this)
7
+ call(*args, &block)
8
+ ensure
9
+ binding_self.pop_this
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ class Proc
16
+ include Kinda::Core::Proc
17
+ end
data/lib/core/this.rb ADDED
@@ -0,0 +1,62 @@
1
+ module Kinda
2
+ module Core
3
+ module This
4
+ def call_with_this(proc, *args, &block)
5
+ return unless proc
6
+ binding_self = proc.binding.eval('self')
7
+ raise "Object #{binding_self.inspect} doesn't respond to Kinda::Core::This methods " +
8
+ "(proc=#{proc.inspect})" unless binding_self.respond_to?(:push_this)
9
+ begin
10
+ binding_self.push_this(self)
11
+ proc.call(*args, &block)
12
+ ensure
13
+ binding_self.pop_this
14
+ end
15
+ end
16
+
17
+ def push_this(object)
18
+ (@these ||= []).push(object)
19
+ end
20
+
21
+ def pop_this
22
+ @these.pop if @these
23
+ end
24
+
25
+ def this
26
+ (@these && @these.last) || self
27
+ end
28
+
29
+ def this_eval(&block)
30
+ this.instance_eval(&block)
31
+ end
32
+
33
+ attr_reader :contextual_methods
34
+
35
+ def contextual_method(*methods)
36
+ methods.each do |method|
37
+ (@contextual_methods ||= []) << method.to_sym
38
+ end
39
+ end
40
+
41
+ def contextual_method?(method)
42
+ to_class.self_and_ancestors.each do |ancestor|
43
+ return true if ancestor.contextual_methods &&
44
+ ancestor.contextual_methods.include?(method.to_sym)
45
+ end
46
+ false
47
+ end
48
+
49
+ def method_missing(method_name, *args, &block)
50
+ if this != self && this.contextual_method?(method_name)
51
+ this.send(method_name, *args, &block)
52
+ else
53
+ super
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ class Object
61
+ include Kinda::Core::This
62
+ end
data/lib/core.rb ADDED
@@ -0,0 +1,10 @@
1
+ require File.join(File.dirname(__FILE__), 'kinda-core', 'module')
2
+ ruby_files = Dir.glob(File.join(File.dirname(__FILE__), 'kinda-core', '*.rb'))
3
+ ruby_files.each { |file| require file }
4
+
5
+ module Kinda
6
+ module Core
7
+ include Accessor
8
+ include Forwardable
9
+ end
10
+ end
data/lib/kinda-core.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'core')
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kinda-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Manuel Vila
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Basic helpers used by other kinda projects
17
+ email: mvila@3base.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - lib/core.rb
26
+ - lib/core/accessor.rb
27
+ - lib/core/forwardable.rb
28
+ - lib/core/functor.rb
29
+ - lib/core/hash.rb
30
+ - lib/core/inspect.rb
31
+ - lib/core/module.rb
32
+ - lib/core/object.rb
33
+ - lib/core/proc.rb
34
+ - lib/core/this.rb
35
+ - lib/kinda-core.rb
36
+ - README.rdoc
37
+ has_rdoc: true
38
+ homepage: http://github.com/kinda/core
39
+ licenses:
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project: kinda-core
60
+ rubygems_version: 1.3.5
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: Basic helpers used by other kinda projects
64
+ test_files: []
65
+