ctx 1.0.0 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
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: []