ctx 1.0.0 → 2.1.3

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.
Files changed (3) hide show
  1. data/README.md +68 -1
  2. data/lib/ctx.rb +63 -33
  3. metadata +36 -4
data/README.md CHANGED
@@ -1,4 +1,71 @@
1
1
  ctx
2
2
  ===
3
3
 
4
- Simple utility to limit method redefinition within the bounds of arbitrary logical scopes
4
+ Simple utility to limit method redefinition within the bounds of arbitrary logical scopes
5
+
6
+ Example
7
+ ===
8
+
9
+ Here, figure it out:
10
+
11
+ require 'ctx'
12
+
13
+ class ::String
14
+ ctx :reversaroo do
15
+ def +(other)
16
+ "#{other.reverse}#{self.reverse}"
17
+ end
18
+ end
19
+ ctx :camels do
20
+ def +(other)
21
+ "#{self.capitalize}#{other.capitalize}"
22
+ end
23
+ end
24
+ ctx :polite do
25
+ def +(other)
26
+ "I say, good day to you there '#{other}', may I introduce you to my good friend '#{self}'?"
27
+ end
28
+ end
29
+ ctx do
30
+ def +(other)
31
+ "#{self} + #{other} = ?"
32
+ end
33
+ end
34
+ end
35
+
36
+ puts "hello" + "world"
37
+ #=> helloworld
38
+
39
+ ctx :camels do
40
+ puts "hello" + "world"
41
+ #=> HelloWorld
42
+
43
+ ctx :polite do
44
+ puts "hello" + "world"
45
+ #=> I say, good day to you there 'world', may I introduce you to my good friend 'hello'?
46
+ end
47
+
48
+ ctx do
49
+ puts "hello" + "world"
50
+ #=> hello + world = ?
51
+ end
52
+ end
53
+
54
+ ctx :reversaroo do
55
+ puts "hello" + "world"
56
+ #=> dlrowolleh
57
+ end
58
+
59
+ puts "hello" + "world"
60
+ #=> helloworld
61
+
62
+
63
+ There are bugs. You'll find them.
64
+
65
+ ---
66
+
67
+ Caveats and such
68
+ ===
69
+
70
+ For whatever goofy reason, this stuff doesn't play well with rspec all the time, particularly if you override stuff the matchers are hoping to also override, like == or =~ on String, or whatnot. Don't do that right now unless you like stuff to break in inexplicable ways. Personally, I do like that kind of stuff, makes life interesting (kind of explains my dating choices, when you get right down to it), but anywhoo, honestly, it's your call.
71
+
data/lib/ctx.rb CHANGED
@@ -1,55 +1,85 @@
1
1
  module CTX
2
2
 
3
3
  class ::Array
4
- def select_first(&block)
5
- selected = nil
6
- each do |item|
7
- break if (selected = block.call(item))
8
- end
9
- selected
4
+ def return_first(&block)
5
+ returned = nil
6
+ each { |item| break if (returned = block.call(item)) }
7
+ returned
10
8
  end
11
9
  end
12
10
 
13
11
  class Context < Hash
14
12
  attr_reader :name
15
- def initialize(name) @name = name.to_sym end
13
+ def initialize(name) @name = name.sym end
16
14
  def eql?(other) @name.eql?(other.name) end
17
15
  def hash() @name.hash end
16
+ def to_s() "#{name} #{super.to_s}" end
17
+ end
18
+
19
+ class ::Object
20
+ def sym() respond_to?(:to_sym) ? to_sym : to_s.to_sym end
21
+ def ctxputs(*args)
22
+ ctxs = @@contexts.map(&:name)[1..-1].join(":")
23
+ ctxs = "[CTX #{ctxs}] " unless ctxs.empty?
24
+ puts "#{ctxs}#{args.map(&:to_s).join(', ')}"
25
+ end
26
+ def ctxp(*args)
27
+ ctxs = @@contexts.map(&:name)[1..-1].join(":")
28
+ ctxs = "[CTX #{ctxs.empty? ? "-" : ctxs}]"
29
+ puts "#{ctxs}\n#{args.map(&:inspect).join("\n")}"
30
+ end
31
+
32
+ @@contexts ||= [Context.new(nil)]
33
+ def ctx(context = :anonymous, &contextual)
34
+ if contextual.nil?
35
+ @@contexts.reverse.first
36
+ else
37
+ @@contexts.push(Context.new(context))
38
+ instance_eval(&contextual)
39
+ @@contexts.pop()
40
+ end
41
+ end
42
+
18
43
  end
19
44
 
20
- class ::BasicObject
45
+ class ::Class
46
+
47
+ def object_methods() self.instance_methods - Object.instance_methods end
48
+ def class_methods() self.singleton_methods - Object.singleton_methods end
49
+ def defined_methods() class_methods | object_methods end
21
50
 
22
- def ctx(name = :anonymous, &scoped) self.class.ctx(name, &scoped) end
51
+ attr_accessor :ctx_methods
23
52
 
24
- class << self
25
- @@contexts = [nil]
26
- def ctx(name = :anonymous, &scoped)
27
- return @@contexts.last if scoped.nil?
53
+ def ctx(context = :anonymous, &contextual)
54
+ @ctx_methods ||= {}
28
55
 
29
- context = Context.new(name)
30
- @@contexts.push(context)
31
- scoped.call(self)
32
- @@contexts.pop
56
+ template = Class.new
57
+ template.class_eval(&contextual)
58
+
59
+ matching = self.object_methods & template.object_methods
60
+ matching.each do |method_name|
61
+ if ctx_methods[method_name].nil?
62
+ ctx_methods[method_name] = {}
63
+ ctx_methods[method_name][nil.sym] = instance_method(method_name)
64
+ end
33
65
  end
34
66
 
35
- def ctx_define(context = :anonymous, method, &definition)
36
- method = method.to_sym
37
- @@ctx_methods ||= {}
38
- @@ctx_methods[method] ||= {}
39
-
40
- if @@ctx_methods[method][nil].nil?
41
- @@ctx_methods[method][nil] = instance_method(method) if method_defined? method
42
- define_method(method) do |*args|
43
- methods = @@ctx_methods[method]
44
- matched = @@contexts.reverse.select_first { |ctx| methods[ctx ? ctx.name : nil] }
45
- matched.bind(self).(*args)
46
- end
67
+ self.class_eval(&contextual)
68
+
69
+ template.object_methods.each do |method_name|
70
+ if ctx_methods[method_name].nil?
71
+ ctx_methods[method_name] = {}
72
+ end
73
+
74
+ ctx_methods[method_name][context] = instance_method(method_name)
75
+
76
+ define_method(method_name) do |*args|
77
+ methods = self.class.ctx_methods[method_name]
78
+ matched = @@contexts.reverse.return_first { |currentctx| methods[currentctx.name] }
79
+ matched.bind(self).(*args)
47
80
  end
48
81
 
49
- scoped_method = "#{context}_#{method}".to_sym
50
- define_method(scoped_method, &definition)
51
- @@ctx_methods[method][context] = instance_method(scoped_method)
52
82
  end
53
83
  end
54
84
  end
55
- end
85
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ctx
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-30 00:00:00.000000000 Z
12
+ date: 2012-11-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -27,7 +27,39 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
- description: Scoped define and context for use in writing more expressive DSLs
30
+ - !ruby/object:Gem::Dependency
31
+ name: rr
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: awesome_print
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Contextual method define
31
63
  email: ctx@chipped.net
32
64
  executables: []
33
65
  extensions: []
@@ -35,7 +67,7 @@ extra_rdoc_files: []
35
67
  files:
36
68
  - lib/ctx.rb
37
69
  - README.md
38
- homepage: http://rubygems.org/gems/ctx
70
+ homepage: https://github.com/gnovos/ctx
39
71
  licenses: []
40
72
  post_install_message:
41
73
  rdoc_options: []