selective_binding 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +23 -0
- data/History.txt +6 -0
- data/Manifest.txt +8 -0
- data/README.rdoc +67 -0
- data/Rakefile +12 -0
- data/bin/selective_binding +3 -0
- data/lib/selective_binding.rb +150 -0
- data/test/test_selective_binding.rb +142 -0
- metadata +108 -0
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
= selective_binding
|
2
|
+
|
3
|
+
* http://github.com/yaksnrainbows/selective_binding
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Create Bindings with selective mappings to an object's methods and attributes.
|
8
|
+
|
9
|
+
== SYNOPSIS:
|
10
|
+
|
11
|
+
Creates a selective binding instance for self and returns
|
12
|
+
the newly created binding:
|
13
|
+
|
14
|
+
selective_binding :attr1, :method1
|
15
|
+
#=> <#Binding>
|
16
|
+
|
17
|
+
Passing a hash as the last argument allows for setting custom attributes.
|
18
|
+
These override any previously defined forwarded methods:
|
19
|
+
|
20
|
+
selective_binding :attr1 => "custom value"
|
21
|
+
#=> <#Binding>
|
22
|
+
|
23
|
+
Passing a block is also supported to set the default value for undefined
|
24
|
+
attributes or methods:
|
25
|
+
|
26
|
+
selective_binding do
|
27
|
+
"default value"
|
28
|
+
end
|
29
|
+
#=> <#Binding>
|
30
|
+
|
31
|
+
== INSTALL:
|
32
|
+
|
33
|
+
* sudo gem install selective_binding
|
34
|
+
|
35
|
+
== DEVELOPERS:
|
36
|
+
|
37
|
+
After checking out the source, run:
|
38
|
+
|
39
|
+
$ rake newb
|
40
|
+
|
41
|
+
This task will install any missing dependencies, run the tests/specs,
|
42
|
+
and generate the RDoc.
|
43
|
+
|
44
|
+
== LICENSE:
|
45
|
+
|
46
|
+
(The MIT License)
|
47
|
+
|
48
|
+
Copyright (c) 2010 Jeremie Castagna
|
49
|
+
|
50
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
51
|
+
a copy of this software and associated documentation files (the
|
52
|
+
'Software'), to deal in the Software without restriction, including
|
53
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
54
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
55
|
+
permit persons to whom the Software is furnished to do so, subject to
|
56
|
+
the following conditions:
|
57
|
+
|
58
|
+
The above copyright notice and this permission notice shall be
|
59
|
+
included in all copies or substantial portions of the Software.
|
60
|
+
|
61
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
62
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
63
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
64
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
65
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
66
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
67
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
|
6
|
+
Hoe.spec 'selective_binding' do
|
7
|
+
developer 'Jeremie Castagna', 'yaksnrainbows@gmail.com'
|
8
|
+
self.summary =
|
9
|
+
"Bindings with selective mappings to object methods and attributes."
|
10
|
+
end
|
11
|
+
|
12
|
+
# vim: syntax=ruby
|
@@ -0,0 +1,150 @@
|
|
1
|
+
##
|
2
|
+
# Create a selective binding. Useful for controlling ERB builds.
|
3
|
+
# The following will allow MyObj instances to provide a binding that will only
|
4
|
+
# expose MyObj#my_attr and MyObj#get_some_value:
|
5
|
+
#
|
6
|
+
# require 'selective_binding'
|
7
|
+
#
|
8
|
+
# class MyObj
|
9
|
+
# attr_accessor :my_attr
|
10
|
+
#
|
11
|
+
# def modify_something
|
12
|
+
# # Don't want this exposed in binding!
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# def get_some_value
|
16
|
+
# # Want this exposed in binding.
|
17
|
+
# "some value"
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def get_binding
|
21
|
+
# selective_binding :my_attr, :get_some_value
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# my_obj = MyObj.new
|
26
|
+
#
|
27
|
+
# eval "get_some_value", my_obj.get_binding
|
28
|
+
# #=> "some value"
|
29
|
+
#
|
30
|
+
# eval "modify_something", my_obj.get_binding
|
31
|
+
# #=> NameError: undefined local variable or method `modify_something'
|
32
|
+
#
|
33
|
+
# Additionally, a block can be passed to selective bindings to fill the role of
|
34
|
+
# a default value, or method_missing.
|
35
|
+
|
36
|
+
class SelectiveBinding
|
37
|
+
|
38
|
+
# Gem Version
|
39
|
+
VERSION = '1.0.0'
|
40
|
+
|
41
|
+
##
|
42
|
+
# Creates a new selective binding with the target object to
|
43
|
+
# create a binding to.
|
44
|
+
|
45
|
+
def initialize target
|
46
|
+
@target = target
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
##
|
51
|
+
# Set the binding instance variable and accessor method.
|
52
|
+
# selective_binding.set :server_name, "blah.com"
|
53
|
+
|
54
|
+
def set key, value=nil, &block
|
55
|
+
value ||= block if block_given?
|
56
|
+
|
57
|
+
instance_variable_set("@#{key}", value)
|
58
|
+
|
59
|
+
eval_str = <<-STR
|
60
|
+
undef #{key} if defined?(#{key})
|
61
|
+
def #{key}(*args, &block)
|
62
|
+
if Proc === @#{key}
|
63
|
+
@#{key}.call(*args, &block)
|
64
|
+
else
|
65
|
+
@#{key}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
STR
|
69
|
+
|
70
|
+
instance_eval eval_str, __FILE__, __LINE__ + 1
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
##
|
75
|
+
# Takes a hash and assign each hash key/value as an attribute:
|
76
|
+
# selective_binding.import_hash :attr1 => "value1",
|
77
|
+
# :attr2 => "value2"
|
78
|
+
|
79
|
+
def import_hash hash
|
80
|
+
hash.each{|k, v| self.set(k, v)}
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
##
|
85
|
+
# Forward a method to the server instance.
|
86
|
+
# binder.forward :method1, :method2, ...
|
87
|
+
|
88
|
+
def forward *method_names
|
89
|
+
method_names.each do |method_name|
|
90
|
+
instance_eval <<-STR, __FILE__, __LINE__ + 1
|
91
|
+
undef #{method_name} if defined?(#{method_name})
|
92
|
+
def #{method_name}(*args, &block)
|
93
|
+
@target.send(#{method_name.to_sym.inspect}, *args, &block)
|
94
|
+
end
|
95
|
+
STR
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
##
|
101
|
+
# Sets the default value for undefined attributes or methods.
|
102
|
+
|
103
|
+
def set_default value=nil, &block
|
104
|
+
set :method_missing, value, &block if value || block_given?
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
##
|
109
|
+
# Retrieve the object's binding.
|
110
|
+
|
111
|
+
def get_binding
|
112
|
+
binding
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
class Object
|
118
|
+
|
119
|
+
##
|
120
|
+
# Creates a selective binding instance for self and returns
|
121
|
+
# the newly created binding:
|
122
|
+
#
|
123
|
+
# selective_binding :attr1, :method1
|
124
|
+
# #=> <#Binding>
|
125
|
+
#
|
126
|
+
# Passing a hash as the last argument allows for setting custom attributes.
|
127
|
+
# These override any previously defined forwarded methods:
|
128
|
+
#
|
129
|
+
# selective_binding :attr1 => "custom value"
|
130
|
+
# #=> <#Binding>
|
131
|
+
#
|
132
|
+
# Passing a block is also supported to set the default value for undefined
|
133
|
+
# attributes or methods:
|
134
|
+
#
|
135
|
+
# selective_binding do
|
136
|
+
# "default value"
|
137
|
+
# end
|
138
|
+
# #=> <#Binding>
|
139
|
+
|
140
|
+
def selective_binding *methods, &block
|
141
|
+
hash_attrib = methods.delete_at(-1) if Hash === methods.last
|
142
|
+
|
143
|
+
binder = SelectiveBinding.new self
|
144
|
+
|
145
|
+
binder.forward(*methods) unless methods.empty?
|
146
|
+
binder.import_hash hash_attrib if hash_attrib
|
147
|
+
binder.set_default(&block) if block_given?
|
148
|
+
binder.get_binding
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "selective_binding"
|
3
|
+
|
4
|
+
class TestSelectiveBinding < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class MockObj
|
7
|
+
attr_accessor :obj_attr1, :obj_attr2, :obj_attr3
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@obj = MockObj.new
|
13
|
+
@obj.obj_attr1 = "value1"
|
14
|
+
@obj.obj_attr2 = "value2"
|
15
|
+
@obj.obj_attr3 = "value3"
|
16
|
+
@binder = SelectiveBinding.new @obj
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def test_set
|
21
|
+
@binder.set :other_attr, "my_value"
|
22
|
+
assert_binding_value @binder, :other_attr => "my_value"
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def test_set_block
|
27
|
+
@binder.set :other_attr do
|
28
|
+
"something else"
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_binding_value @binder, :other_attr => "something else"
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def test_set_value_block
|
36
|
+
@binder.set :other_attr, "thing" do
|
37
|
+
"block value"
|
38
|
+
end
|
39
|
+
|
40
|
+
assert_binding_value @binder, :other_attr => "thing"
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def test_import_hash
|
45
|
+
@binder.import_hash :attr1 => "val1",
|
46
|
+
:attr2 => "val2"
|
47
|
+
|
48
|
+
assert_binding_value @binder, :attr1 => "val1",
|
49
|
+
:attr2 => "val2"
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def test_forward
|
54
|
+
@binder.forward :obj_attr1, :obj_attr2
|
55
|
+
|
56
|
+
assert_binding_value @binder, :obj_attr1 => @obj.obj_attr1,
|
57
|
+
:obj_attr2 => @obj.obj_attr2
|
58
|
+
|
59
|
+
assert_not_binding_value @binder, :obj_attr3
|
60
|
+
|
61
|
+
@binder.forward :obj_attr3
|
62
|
+
assert_binding_value @binder, :obj_attr3 => @obj.obj_attr3
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def test_set_default
|
67
|
+
@binder.forward :obj_attr1, :obj_attr2
|
68
|
+
@binder.set_default "DEFAULT VALUE!"
|
69
|
+
|
70
|
+
assert_binding_value @binder, :undefined => "DEFAULT VALUE!",
|
71
|
+
:obj_attr1 => @obj.obj_attr1,
|
72
|
+
:obj_attr2 => @obj.obj_attr2
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def test_set_default_block
|
77
|
+
@binder.forward :obj_attr1, :obj_attr2
|
78
|
+
|
79
|
+
@binder.set_default do
|
80
|
+
"NEW DEFAULT VALUE!"
|
81
|
+
end
|
82
|
+
|
83
|
+
assert_binding_value @binder, :undefined => "NEW DEFAULT VALUE!",
|
84
|
+
:obj_attr1 => @obj.obj_attr1,
|
85
|
+
:obj_attr2 => @obj.obj_attr2
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
def test_obj_selective_binding
|
90
|
+
b = selective_binding :forwarded_method
|
91
|
+
assert_binding_value b, :forwarded_method => forwarded_method
|
92
|
+
assert_not_binding_value b, :not_forwarded
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def test_obj_selective_binding_hash
|
97
|
+
b = selective_binding :forwarded_method, :forwarded_method => "custom attr"
|
98
|
+
|
99
|
+
assert_binding_value b, :forwarded_method => "custom attr"
|
100
|
+
|
101
|
+
assert_not_binding_value b, :not_forwarded
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
def test_obj_selective_binding_block
|
106
|
+
b = selective_binding do
|
107
|
+
"DEFAULT VALUE!"
|
108
|
+
end
|
109
|
+
|
110
|
+
assert_binding_value b, :forwarded_method => "DEFAULT VALUE!"
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def not_forwarded
|
117
|
+
raise "This method should not be accessible from the binding"
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def forwarded_method
|
122
|
+
"FORWARDED METHOD"
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
def assert_binding_value binding, hash
|
127
|
+
binding = binding.get_binding if SelectiveBinding === binding
|
128
|
+
hash.each do |key, value|
|
129
|
+
assert_equal eval("#{key}", binding), value
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def assert_not_binding_value binding, *keys
|
135
|
+
binding = binding.get_binding if SelectiveBinding === binding
|
136
|
+
keys.each do |key|
|
137
|
+
assert_raises NameError do
|
138
|
+
eval("#{key}", binding)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: selective_binding
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jeremie Castagna
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-18 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rubyforge
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 0
|
33
|
+
- 4
|
34
|
+
version: 2.0.4
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: hoe
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 19
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 6
|
49
|
+
- 2
|
50
|
+
version: 2.6.2
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
description: ""
|
54
|
+
email:
|
55
|
+
- yaksnrainbows@gmail.com
|
56
|
+
executables:
|
57
|
+
- selective_binding
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
extra_rdoc_files:
|
61
|
+
- History.txt
|
62
|
+
- Manifest.txt
|
63
|
+
files:
|
64
|
+
- .autotest
|
65
|
+
- History.txt
|
66
|
+
- Manifest.txt
|
67
|
+
- README.rdoc
|
68
|
+
- Rakefile
|
69
|
+
- bin/selective_binding
|
70
|
+
- lib/selective_binding.rb
|
71
|
+
- test/test_selective_binding.rb
|
72
|
+
has_rdoc: true
|
73
|
+
homepage:
|
74
|
+
licenses: []
|
75
|
+
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options:
|
78
|
+
- --main
|
79
|
+
- README.txt
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
version: "0"
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project: selective_binding
|
103
|
+
rubygems_version: 1.3.7
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: Bindings with selective mappings to object methods and attributes.
|
107
|
+
test_files:
|
108
|
+
- test/test_selective_binding.rb
|