ObjectProxy 1.0.1
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/History.txt +10 -0
- data/Manifest.txt +7 -0
- data/README.txt +77 -0
- data/Rakefile +13 -0
- data/lib/object_proxy.rb +40 -0
- data/lib/object_proxy_safe_hash.rb +30 -0
- data/test/test_object_proxy.rb +59 -0
- data/test/test_object_proxy_safe_hash.rb +10 -0
- metadata +72 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= ObjectProxy
|
2
|
+
|
3
|
+
* http://github.com/JackDanger/object_proxy/tree/master
|
4
|
+
|
5
|
+
== DESCRIPTION
|
6
|
+
|
7
|
+
ObjectProxy provides a proxied interface to Ruby objects. It lets you add methods to objects that don't normally support them.
|
8
|
+
|
9
|
+
== USAGE
|
10
|
+
|
11
|
+
A simple extension to a fixnum:
|
12
|
+
|
13
|
+
fixnum = ObjectProxy.new(1234)
|
14
|
+
# => 1234
|
15
|
+
fixnum.proxy_class.class_eval do
|
16
|
+
define_method :hi_there do
|
17
|
+
'Ahoy!'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
# => #<Proc:0x018f58f8>
|
21
|
+
fixnum.size
|
22
|
+
# => 4
|
23
|
+
fixnum.hi_there
|
24
|
+
# => Ahoy!
|
25
|
+
|
26
|
+
A more complex example where a string is able to update itself from a text file
|
27
|
+
|
28
|
+
class FetchedString < ObjectProxy
|
29
|
+
def initialize(target, filename)
|
30
|
+
@target = target
|
31
|
+
@filename = filename
|
32
|
+
end
|
33
|
+
|
34
|
+
def update
|
35
|
+
@target = File.read(filename)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# write a string into a file
|
40
|
+
File.open('/tmp/greeting.txt', 'w') {|f| f.write('welcome')}
|
41
|
+
|
42
|
+
string = FetchedString.new('hey there', '/tmp/greeting.txt')
|
43
|
+
# => 'hey there'
|
44
|
+
string.class
|
45
|
+
# => String
|
46
|
+
string.update
|
47
|
+
# => 'welcome'
|
48
|
+
|
49
|
+
|
50
|
+
== INSTALL:
|
51
|
+
|
52
|
+
* sudo gem install object_proxy
|
53
|
+
|
54
|
+
== LICENSE:
|
55
|
+
|
56
|
+
(The MIT License)
|
57
|
+
|
58
|
+
Copyright (c) 2008 FIX
|
59
|
+
|
60
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
61
|
+
a copy of this software and associated documentation files (the
|
62
|
+
'Software'), to deal in the Software without restriction, including
|
63
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
64
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
65
|
+
permit persons to whom the Software is furnished to do so, subject to
|
66
|
+
the following conditions:
|
67
|
+
|
68
|
+
The above copyright notice and this permission notice shall be
|
69
|
+
included in all copies or substantial portions of the Software.
|
70
|
+
|
71
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
72
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
73
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
74
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
75
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
76
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
77
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/object_proxy.rb'
|
6
|
+
|
7
|
+
Hoe.new('ObjectProxy', ObjectProxy::VERSION) do |p|
|
8
|
+
# p.rubyforge_name = 'ObjectProxyx' # if different than lowercase project name
|
9
|
+
p.remote_rdoc_dir = '' # Release to root
|
10
|
+
p.developer('Jack Danger Canty', 'rubygems_object_proxy@6brand.com')
|
11
|
+
end
|
12
|
+
|
13
|
+
# vim: syntax=Ruby
|
data/lib/object_proxy.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'object_proxy_safe_hash'
|
4
|
+
|
5
|
+
class ObjectProxy
|
6
|
+
|
7
|
+
VERSION = '1.0.1'
|
8
|
+
|
9
|
+
SAFE_METHODS = [:__id__, :__send__, :nil, :nil?, :send, :send!, :proxy_class, :proxy_respond_to?]
|
10
|
+
|
11
|
+
alias_method :proxy_class, :class
|
12
|
+
alias_method :proxy_respond_to?, :respond_to?
|
13
|
+
|
14
|
+
instance_methods.each do |method|
|
15
|
+
undef_method method unless SAFE_METHODS.include?(method.to_sym)
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(target)
|
19
|
+
@target = target
|
20
|
+
end
|
21
|
+
|
22
|
+
def is_object_proxy?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def target
|
27
|
+
@target
|
28
|
+
end
|
29
|
+
|
30
|
+
def respond_to?(*args)
|
31
|
+
proxy_respond_to?(*args) || @target.respond_to?(*args)
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
# delegate nearly all method calls to the @target object
|
37
|
+
def method_missing(method, *args, &block)
|
38
|
+
@target.send(method, *args, &block)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# This extension fixes that object proxies aren't interchangeable with their target
|
2
|
+
# value for the purposes of hash lookup
|
3
|
+
# The following becomes true in MRI:
|
4
|
+
#
|
5
|
+
# {'some_string' => true}[ObjectProxy.new('some_string')]
|
6
|
+
#
|
7
|
+
|
8
|
+
module ObjectProxySafeHash
|
9
|
+
def self.included(klass)
|
10
|
+
klass.class_eval do
|
11
|
+
|
12
|
+
define_method "[]_with_object_proxy" do |value|
|
13
|
+
if value.respond_to?(:is_object_proxy?) && value.is_object_proxy?
|
14
|
+
value = value.target
|
15
|
+
end
|
16
|
+
send "[]_without_object_proxy", value
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method '[]_without_object_proxy', '[]'
|
20
|
+
alias_method '[]', '[]_with_object_proxy'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Hash
|
27
|
+
unless included_modules.include?(ObjectProxySafeHash)
|
28
|
+
include ObjectProxySafeHash
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/object_proxy'
|
3
|
+
|
4
|
+
class OneHundredProxy < ObjectProxy
|
5
|
+
def initialize
|
6
|
+
@target = 100
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ObjectProxyTest < Test::Unit::TestCase
|
11
|
+
def test_does_not_respond_to_target
|
12
|
+
assert_raises(NoMethodError) { ObjectProxy.new('some_value').responds_to?(:target) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_has_target_method_that_returns_the_provided_value
|
16
|
+
assert_equal 'target', ObjectProxy.new('target')
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_target_object_does_not_have_identity_with_initialized_object
|
20
|
+
object = Object.new
|
21
|
+
assert !object.equal?(ObjectProxy.new(object))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_class_method_is_passed_to_target
|
25
|
+
assert_equal String, ObjectProxy.new('some value').class
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_send_is_passed_to_target
|
29
|
+
object = 'ABCDEF'
|
30
|
+
assert_equal object.send(:length), ObjectProxy.new(object).send(:length)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_proxy_class_accesses_the_class_of_the_object_proxy
|
34
|
+
assert_equal ObjectProxy, ObjectProxy.new('value').proxy_class
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_proxy_class_allows_methods_added_to_the_proxy_class
|
38
|
+
object = 'ABCDEF'
|
39
|
+
proxy = ObjectProxy.new(object)
|
40
|
+
proxy.proxy_class.class_eval do
|
41
|
+
define_method :return_target do
|
42
|
+
@target
|
43
|
+
end
|
44
|
+
end
|
45
|
+
assert_equal object, proxy.return_target
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_method_missing_errors_are_raised_from_the_target_object
|
49
|
+
begin
|
50
|
+
ObjectProxy.new(12345).howzitgoin
|
51
|
+
rescue => e
|
52
|
+
assert_equal %Q(undefined method `howzitgoin' for 12345:Fixnum), e.message
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_subclass_of_object_proxy_can_set_target_however_it_wants
|
57
|
+
assert_equal 100, OneHundredProxy.new.target
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/object_proxy'
|
3
|
+
|
4
|
+
class ObjectProxySafeHashTest < Test::Unit::TestCase
|
5
|
+
def test_object_proxy_identifies_as_target_for_hash_lookup
|
6
|
+
object = 'a string'
|
7
|
+
hash = {object => true}
|
8
|
+
assert hash[ObjectProxy.new(object)]
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ObjectProxy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jack Danger Canty
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-03-06 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.5.1
|
23
|
+
version:
|
24
|
+
description: ObjectProxy provides a proxied interface to Ruby objects. It lets you add methods to objects that don't normally support them.
|
25
|
+
email:
|
26
|
+
- rubygems_object_proxy@6brand.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
files:
|
36
|
+
- History.txt
|
37
|
+
- Manifest.txt
|
38
|
+
- README.txt
|
39
|
+
- Rakefile
|
40
|
+
- lib/object_proxy.rb
|
41
|
+
- lib/object_proxy_safe_hash.rb
|
42
|
+
- test/test_object_proxy.rb
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: http://github.com/JackDanger/object_proxy/tree/master
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options:
|
47
|
+
- --main
|
48
|
+
- README.txt
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project: objectproxy
|
66
|
+
rubygems_version: 1.0.1
|
67
|
+
signing_key:
|
68
|
+
specification_version: 2
|
69
|
+
summary: ObjectProxy provides a proxied interface to Ruby objects
|
70
|
+
test_files:
|
71
|
+
- test/test_object_proxy.rb
|
72
|
+
- test/test_object_proxy_safe_hash.rb
|