mattmatt-threadlocal-attr-accessor 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.
@@ -0,0 +1,29 @@
1
+ Thread-local attr_accessor
2
+ ========
3
+
4
+ Think attr_accessor, only thread-local. Figures, huh?
5
+
6
+ require 'threadsafe-attr-accessor'
7
+
8
+ class Person
9
+ tl_attr_accessor :name
10
+ tl_attr_writer :spouse
11
+ tl_attr_reader :fullname
12
+ end
13
+
14
+ Yeah, I know the examples above probably aren't good
15
+ candidates for thread-local attribute accessors, but
16
+ you get the gist.
17
+
18
+ Works for classes too:
19
+
20
+ class Person
21
+ tl_cattr_accessor :connection
22
+ end
23
+
24
+ License
25
+ =======
26
+
27
+ (c) 2009 Mathias Meyer
28
+
29
+ MIT Baby!
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |s|
8
+ s.name = 'threadlocal-attr-accessor'
9
+ s.summary = 'Think attr_accessor, only thread-local. Figures, huh?'
10
+ s.email = 'meyer@paperplanes.de'
11
+ s.homepage = 'http://github.com/mattmatt/threadlocal-attr-accessor'
12
+ s.authors = ["Mathias Meyer"]
13
+ s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
14
+ end
15
+ rescue LoadError
16
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
17
+ end
18
+
19
+ desc "Default Task"
20
+ task :default => ["test"]
21
+
22
+ desc "Runs the unit tests"
23
+ task :test => "test:unit"
24
+
25
+ namespace :test do
26
+ desc "Unit tests"
27
+ Rake::TestTask.new(:unit) do |t|
28
+ t.libs << 'test'
29
+ t.pattern = "test/*_test.rb"
30
+ t.verbose = true
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 0
3
+ :patch: 2
4
+ :major: 0
@@ -0,0 +1,28 @@
1
+ class Module
2
+ def tl_attr_accessor(*names)
3
+ tl_attr_reader(*names)
4
+ tl_attr_writer(*names)
5
+ end
6
+
7
+ def tl_attr_reader(*names)
8
+ names.each do |name|
9
+ define_method(name) do
10
+ Thread.current["#{self.class.name.downcase}_#{object_id}_#{name.to_s}"]
11
+ end
12
+ end
13
+ end
14
+
15
+ def tl_attr_writer(*names)
16
+ names.each do |name|
17
+ define_method("#{name}=".to_sym) do |new_value|
18
+ Thread.current["#{self.class.name.downcase}_#{object_id}_#{name.to_s}"] = new_value
19
+ end
20
+ end
21
+ end
22
+
23
+ def tl_attr(name, writable = false)
24
+ tl_attr_reader(name)
25
+
26
+ tl_attr_writer(name) if writable
27
+ end
28
+ end
@@ -0,0 +1,138 @@
1
+ require 'test_helper'
2
+
3
+ class Person
4
+ tl_attr_accessor :connection
5
+ tl_attr_reader :owner
6
+ tl_attr_writer :job
7
+
8
+ tl_attr :name, true
9
+ tl_attr :firstname
10
+ tl_attr :nickname, false
11
+
12
+ tl_attr_accessor :other_connection, :real_connection
13
+ tl_attr_reader :spouse, :children
14
+ tl_attr_writer :occupation, :hobbies
15
+ end
16
+
17
+ class AttrAccessorTest < Test::Unit::TestCase
18
+ context "with a person instance" do
19
+ setup do
20
+ @person = Person.new
21
+ end
22
+
23
+ context "and a connection" do
24
+ setup do
25
+ @person.connection = :connection
26
+ end
27
+
28
+ should "keep the connection in a thread local variable" do
29
+ assert_not_nil Thread.current["person_#{@person.object_id}_connection"]
30
+ end
31
+
32
+ should "be nil in a different thread" do
33
+ person = @person
34
+ t = Thread.new {Thread.current[:result] = person.connection}
35
+ t.join
36
+ assert_nil t[:result]
37
+ assert_not_nil person.connection
38
+ end
39
+
40
+ should "store different values for different threads" do
41
+ person = @person
42
+ t = Thread.new do
43
+ person.connection = :other_connection
44
+ Thread.current[:result] = person.connection
45
+ end
46
+ t.join
47
+ assert_equal :other_connection, t[:result]
48
+ end
49
+ end
50
+
51
+ context "and an owner" do
52
+ setup do
53
+ Thread.current["person_#{@person.object_id}_owner"] = :god
54
+ end
55
+
56
+ should "return the value from thread local" do
57
+ assert_equal :god, @person.owner
58
+ end
59
+
60
+ should "be nil in a different thread" do
61
+ person = @person
62
+ t = Thread.new do
63
+ Thread.current[:result] = person.owner
64
+ end
65
+ t.join
66
+ assert_nil t[:result]
67
+ assert_equal :god, person.owner
68
+ end
69
+
70
+ should "not have a setter defined" do
71
+ assert !@person.respond_to?("owner=")
72
+ end
73
+ end
74
+
75
+ context "and a job" do
76
+ setup do
77
+ @person.job = :janitor
78
+ end
79
+
80
+ should "store the job in a thread local" do
81
+ assert_equal :janitor, Thread.current["person_#{@person.object_id}_job"]
82
+ end
83
+
84
+ should "not have a getter" do
85
+ assert !@person.respond_to?(:job)
86
+ end
87
+
88
+ should "be not overwrite from a different" do
89
+ person = @person
90
+ t = Thread.new do
91
+ person.job = :ceo
92
+ end
93
+ t.join
94
+ assert_equal :janitor, Thread.current["person_#{@person.object_id}_job"]
95
+ end
96
+ end
97
+
98
+ context "with multiple variable names" do
99
+ should "create accessors for all variable names" do
100
+ assert @person.respond_to?(:other_connection)
101
+ assert @person.respond_to?(:real_connection)
102
+ assert @person.respond_to?(:real_connection=)
103
+ assert @person.respond_to?(:other_connection=)
104
+ end
105
+
106
+ should "create only read-only accessors for all variable names" do
107
+ assert @person.respond_to?(:spouse)
108
+ assert @person.respond_to?(:children)
109
+ assert !@person.respond_to?(:spouse=)
110
+ assert !@person.respond_to?(:children=)
111
+ end
112
+
113
+ should "create only write accessors for all variable names" do
114
+ assert !@person.respond_to?(:occupation)
115
+ assert !@person.respond_to?(:hobbies)
116
+ assert @person.respond_to?(:occupation=)
117
+ assert @person.respond_to?(:hobbies=)
118
+ end
119
+ end
120
+
121
+ context "with attr" do
122
+ should "create a getter and no setter by default" do
123
+ assert @person.respond_to?(:firstname)
124
+ assert !@person.respond_to?(:firstname=)
125
+ end
126
+
127
+ should "create a getter and setter with second parameter true" do
128
+ assert @person.respond_to?(:name)
129
+ assert @person.respond_to?(:name=)
130
+ end
131
+
132
+ should "create only getter when second parameter false" do
133
+ assert @person.respond_to?(:nickname)
134
+ assert !@person.respond_to?(:nickname=)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,5 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
+ require 'test/unit'
3
+ require 'rubygems'
4
+ require 'shoulda'
5
+ require 'core_ext/module'
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mattmatt-threadlocal-attr-accessor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Mathias Meyer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-26 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: meyer@paperplanes.de
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - Rakefile
26
+ - README.md
27
+ - VERSION.yml
28
+ - lib/core_ext
29
+ - lib/core_ext/module.rb
30
+ - test/attr_accessor_test.rb
31
+ - test/test_helper.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/mattmatt/threadlocal-attr-accessor
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --inline-source
37
+ - --charset=UTF-8
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ requirements: []
53
+
54
+ rubyforge_project:
55
+ rubygems_version: 1.2.0
56
+ signing_key:
57
+ specification_version: 2
58
+ summary: Think attr_accessor, only thread-local. Figures, huh?
59
+ test_files: []
60
+