codeodor-with 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-01-12
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,17 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README
4
+ README.rdoc
5
+ Rakefile
6
+ lib/with.rb
7
+ lib/with_on_object.rb
8
+ lib/with_sexp_processor.rb
9
+ script/console
10
+ script/destroy
11
+ script/generate
12
+ test/foo.rb
13
+ test/test_helper.rb
14
+ test/test_with.rb
15
+ test/with_on_object_test.rb
16
+ test/with_test.rb
17
+ with.tmproj
data/README ADDED
@@ -0,0 +1,105 @@
1
+ = with
2
+
3
+ * http://github.com/codeodor/with/tree/master
4
+
5
+ == DESCRIPTION:
6
+
7
+ I sometimes get a little descriptive with my variable names, so when you're doing a lot of work
8
+ specifically with one object, it gets especially ugly and repetetive, making the code harder to
9
+ read than it needs to be:
10
+
11
+ @contract_participants_on_drugs.contract_id = params[:contract_id]
12
+ @contract_participants_on_drugs.participant_name = params[:participant_name]
13
+ @contract_participants_on_drugs.drug_conviction = DrugConvictions.find(:wtf => 'this is getting ridiculous')
14
+ ...
15
+
16
+ And so on. It gets ridiculous.
17
+
18
+ Utility Belt implements a with(object) method via a change to Object:
19
+
20
+ class Object
21
+ #utility belt implementation
22
+ def with(object, &block)
23
+ object.instance_eval &block
24
+ end
25
+ end
26
+
27
+ Unfortunately, that just executes the block in the context of the object, so there isn't any
28
+ crossover, nor can you perform assignments with attr_accessors (that I was able to do, anyway).
29
+
30
+ So, here's With.object() to fill the void.
31
+
32
+ With.object(@foo) do
33
+ a = "wtf"
34
+ b = "this is not as bad"
35
+ end
36
+
37
+ In the above example, @foo.a and @foo.b are the variables getting set.
38
+
39
+ If you prefer, you can require 'with_on_object' instead and use the notation with(object) do ... end.
40
+
41
+ The tests in the /test directory offer more examples of what's been implemented and tested so far
42
+ (except where noted - namely performing assignment to a variable that was declared outside the
43
+ block, and is not on @foo).
44
+
45
+ Not everything is working yet, but it works for the simplest, most common cases I've run up
46
+ against. More complex tests are on the way, along with code to make them pass.
47
+
48
+ Special thanks to Reg Braithwaite, for help and ideas along the way.
49
+
50
+
51
+ == FEATURES/PROBLEMS:
52
+
53
+ The tests in the /test directory offer more examples of what's been implemented and tested so far
54
+ (except where noted - namely performing assignment to a variable that was declared outside the
55
+ block, and is not on @foo).
56
+
57
+ == SYNOPSIS:
58
+
59
+ require 'with'
60
+ With.object(@foo) do
61
+ a = "wtf"
62
+ b = "this is not as bad"
63
+ end
64
+
65
+ or
66
+
67
+ require 'with_on_object'
68
+ with(@foo) do
69
+ a = "wtf"
70
+ b = "this is not as bad"
71
+ end
72
+
73
+ == REQUIREMENTS:
74
+
75
+ * Ruby2Ruby
76
+ * ParseTree
77
+
78
+ == INSTALL:
79
+
80
+ * sudo gem install codeodor-with -s http://gems. github.com
81
+
82
+ == LICENSE:
83
+
84
+ (The MIT License)
85
+
86
+ Copyright (c) 2009 FIX
87
+
88
+ Permission is hereby granted, free of charge, to any person obtaining
89
+ a copy of this software and associated documentation files (the
90
+ 'Software'), to deal in the Software without restriction, including
91
+ without limitation the rights to use, copy, modify, merge, publish,
92
+ distribute, sublicense, and/or sell copies of the Software, and to
93
+ permit persons to whom the Software is furnished to do so, subject to
94
+ the following conditions:
95
+
96
+ The above copyright notice and this permission notice shall be
97
+ included in all copies or substantial portions of the Software.
98
+
99
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
100
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
101
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
102
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
103
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
104
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
105
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/with'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('with', With::VERSION) do |p|
7
+ p.developer('Sammy Larbi', 'sam@codeodor.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.rubyforge_name = p.name # TODO this is default value
10
+ # p.extra_deps = [
11
+ # ['activesupport','>= 2.0.2'],
12
+ # ]
13
+ p.extra_dev_deps = [
14
+ ['newgem', ">= #{::Newgem::VERSION}"]
15
+ ]
16
+
17
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
18
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
19
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
20
+ p.rsync_args = '-av --delete --ignore-errors'
21
+ end
22
+
23
+ require 'newgem/tasks' # load /tasks/*.rake
24
+ Dir['tasks/**/*.rake'].each { |t| load t }
25
+
26
+ # TODO - want other tests/tasks run by default? Add them to the list
27
+ # task :default => [:spec, :features]
data/lib/with.rb ADDED
@@ -0,0 +1,96 @@
1
+ require 'with_sexp_processor'
2
+ require 'parse_tree'
3
+
4
+ class With
5
+ VERSION = "0.0.1"
6
+ def self.object(the_object, &block)
7
+ @the_object = the_object
8
+ @original_context = block.binding
9
+
10
+ anonymous_class = Class.new
11
+ anonymous_class.instance_eval { define_method("the_block", block) }
12
+ anonymous_class_as_sexp = ParseTree.translate(anonymous_class)
13
+
14
+ our_block_sexp = anonymous_class_as_sexp[3][2][2]
15
+ our_block_sexp = transform(our_block_sexp)
16
+
17
+ transformed_block = lambda { eval(WithSexpProcessor.new.process(our_block_sexp)) } #, block.binding) }
18
+ transformed_block.call
19
+ end
20
+
21
+ private
22
+ def self.convert_single_statement_to_block(node)
23
+ node = [:block, node] if node[0] != :block
24
+ return node
25
+ end
26
+
27
+ def self.statements_to_process
28
+ [:dasgn_curr, :lasgn, :fcall, :vcall]
29
+ end
30
+
31
+ def self.transform( node )
32
+ node = convert_single_statement_to_block node
33
+
34
+ node.each_with_index do |statement, i|
35
+ next if i == 0
36
+
37
+ statement_type = statement[0]
38
+ statement = self.method("transform_#{statement_type.to_s}").call(statement) if statements_to_process.include? statement_type
39
+ node[i] = statement
40
+ end
41
+
42
+ return node
43
+ end
44
+
45
+ def self.transform_dasgn_curr statement
46
+ var_name = statement[1].to_s
47
+ value = statement[2]
48
+ new_method = (var_name+"=").to_sym
49
+
50
+ #binds to original context since we lose original_object name and cannot eval in that context
51
+ value[1] = eval(value[1].to_s, @original_context) if (value[0]==:lvar || value[0]==:vcall) && !@the_object.respond_to?(value[1].to_s)
52
+
53
+ if value[0]==:fcall
54
+ func = value[1]
55
+ args = value[2]
56
+ arg_list = ""
57
+ args.each_with_index do |arg, j|
58
+ next if j == 0
59
+
60
+ arg[1] = eval(arg[1].to_s, @original_context) if arg[0] != :lit
61
+
62
+ arg_list << arg[1].to_s
63
+ arg_list << "," if j < args.length-1
64
+ end
65
+ funcall = "#{func}(#{arg_list})"
66
+
67
+ value=[:lit, eval(funcall, @original_context)]
68
+ end
69
+
70
+ statement = [:attrasgn, [:lvar, :the_object], new_method, value]
71
+ end
72
+
73
+ def self.transform_lasgn statement
74
+ method = statement[2][1]
75
+ if @the_object.respond_to?(method)
76
+ lvar = statement[1]
77
+ statement = [:lasgn, lvar, [:call, [:lvar, :the_object], method]]
78
+ end
79
+ end
80
+
81
+ def self.transform_fcall statement
82
+ method = statement[1]
83
+ args = statement[2]
84
+ args.each_with_index do |arg, j|
85
+ next if j == 0
86
+ arg[1] = eval(arg[1].to_s, @original_context) if arg[0] == :lvar && !@the_object.respond_to?(arg[1].to_s)
87
+ end
88
+ statement = [:call, [:lvar, :the_object], method, args]
89
+ end
90
+
91
+ def self.transform_vcall statement
92
+ method = statement[1]
93
+ statement = [:call, [:lvar, :the_object], method]
94
+ end
95
+
96
+ end
@@ -0,0 +1,7 @@
1
+ require 'with'
2
+ class Object
3
+ def with(object, &block)
4
+ With.object(object, &block)
5
+ end
6
+ end
7
+
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'ruby2ruby'
3
+
4
+ class WithSexpProcessor < Ruby2Ruby
5
+
6
+ def process_vcall(exp)
7
+ exp.shift.to_s
8
+ end
9
+
10
+ def process(exp)
11
+ hacked=true && hack_nil unless nil.respond_to? "empty?"
12
+ result = super(exp)
13
+ unhack_nil if hacked
14
+ return result
15
+ end
16
+
17
+ private
18
+ def hack_nil
19
+ ::NilClass.module_eval do
20
+ def empty?
21
+ true
22
+ end
23
+ end
24
+ end
25
+
26
+ def unhack_nil
27
+ ::NilClass.module_eval do
28
+ def empty?
29
+ throw NoMethodError, "undefined method `empty?' for nil:NilClass"
30
+ end
31
+ end
32
+ end
33
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/with.rb'}"
9
+ puts "Loading with gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/test/foo.rb ADDED
@@ -0,0 +1,21 @@
1
+ class Foo
2
+ attr_accessor :get, :a, :b
3
+ def initialize
4
+ @get = "get!"
5
+ @a = 'a'
6
+ @b = 'b'
7
+ end
8
+
9
+ def show
10
+ puts inspect
11
+ end
12
+
13
+ def change
14
+ @a = "changed!"
15
+ end
16
+
17
+ def set(c, d)
18
+ @a = c
19
+ @b = d
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/with'
data/test/test_with.rb ADDED
@@ -0,0 +1,103 @@
1
+ require 'with'
2
+ require 'test/unit'
3
+ require 'foo'
4
+
5
+
6
+
7
+ class TestWith < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @foo = Foo.new
11
+ end
12
+
13
+ def test_With_works_with_attr_accessor_assignment
14
+ foo = Foo.new
15
+ With.object(foo) do
16
+ get = 'got!'
17
+ end
18
+ assert(foo.get == "got!")
19
+ end
20
+
21
+ def test_With_works_with_two_attr_accessor_assignments
22
+ # Seems strange, but one line blocks don't show up as blocks after running through ParseTree,
23
+ # so this exercises the more common case, whereas the previous test exercises the uncommon one.
24
+ With.object(@foo) do
25
+ get = 'got!'
26
+ a = 'b'
27
+ end
28
+ assert(@foo.get == "got!")
29
+ assert(@foo.a == "b")
30
+ end
31
+
32
+ def test_With_works_with_method_call_no_args
33
+ With.object(@foo) do
34
+ get = 'got!'
35
+ change
36
+ end
37
+ assert(@foo.a == "changed!")
38
+ end
39
+
40
+ def test_With_works_with_method_call_with_args
41
+ With.object @foo do
42
+ set("c", "d")
43
+ set("d", "e")
44
+ end
45
+ assert @foo.a == "d"
46
+ assert @foo.b == "e"
47
+ end
48
+
49
+ def test_With_ignores_calls_to_methods_where_foo_respond_to?_is_false
50
+ With.object(@foo) do
51
+ puts
52
+ end
53
+ assert( true )
54
+ end
55
+
56
+ def test_With_works_with_assignment_to_outside_method_call_no_args
57
+ def outter
58
+ 5
59
+ end
60
+ With.object(@foo) do
61
+ a = outter
62
+ end
63
+
64
+ assert(@foo.a == 5)
65
+ end
66
+
67
+ def test_With_works_with_assignment_to_outside_lvar
68
+ outter = "outside"
69
+ With.object(@foo) do
70
+ outter = get
71
+ end
72
+ assert( outter == @foo.get )
73
+ #this fails. unsure how / if it should stay as part of the spec
74
+ #problem is that (as far as I can tell) it will need to evaluate the post-transformation
75
+ #block in the original context, whereas it currently needs to be executed in a diff one
76
+ #this would be a lot easier - less transforms on other specs - if we could find the variable
77
+ #name of "@foo" within With.object
78
+ end
79
+
80
+ def test_With_works_with_assignment_to_outside_method_call_with_args
81
+ def f(x,y)
82
+ 398
83
+ end
84
+ With.object(@foo) do
85
+ a = f(1,3)
86
+ end
87
+ assert(@foo.a == 398)
88
+ end
89
+
90
+ def test_With_works_with_method_call_with_args_using_non_literals
91
+ def f2(x,y)
92
+ 398
93
+ end
94
+ x = 2
95
+ y = 5
96
+ With.object(@foo) do
97
+ a = f2(x,y)
98
+ end
99
+ assert(@foo.a == 398)
100
+ end
101
+
102
+
103
+ end
@@ -0,0 +1,101 @@
1
+ require '../lib/with_on_object'
2
+ require 'test/unit'
3
+ require 'foo'
4
+
5
+ class TestWithOnObject < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @foo = Foo.new
9
+ end
10
+
11
+ def test_With_works_with_attr_accessor_assignment
12
+ foo = Foo.new
13
+ with(foo) do
14
+ get = 'got!'
15
+ end
16
+ assert(foo.get == "got!")
17
+ end
18
+
19
+ def test_With_works_with_two_attr_accessor_assignments
20
+ # Seems strange, but one line blocks don't show up as blocks after running through ParseTree,
21
+ # so this exercises the more common case, whereas the previous test exercises the uncommon one.
22
+ with(@foo) do
23
+ get = 'got!'
24
+ a = 'b'
25
+ end
26
+ assert(@foo.get == "got!")
27
+ assert(@foo.a == "b")
28
+ end
29
+
30
+ def test_With_works_with_method_call_no_args
31
+ with(@foo) do
32
+ get = 'got!'
33
+ change
34
+ end
35
+ assert(@foo.a == "changed!")
36
+ end
37
+
38
+ def test_With_works_with_method_call_with_args
39
+ With.object @foo do
40
+ set("c", "d")
41
+ set("d", "e")
42
+ end
43
+ assert @foo.a == "d"
44
+ assert @foo.b == "e"
45
+ end
46
+
47
+ def test_With_ignores_calls_to_methods_where_foo_respond_to?_is_false
48
+ with(@foo) do
49
+ puts
50
+ end
51
+ assert( true )
52
+ end
53
+
54
+ def test_With_works_with_assignment_to_outside_method_call_no_args
55
+ def outter
56
+ 5
57
+ end
58
+ with(@foo) do
59
+ a = outter
60
+ end
61
+
62
+ assert(@foo.a == 5)
63
+ end
64
+
65
+ def test_With_works_with_assignment_to_outside_lvar
66
+ outter = "outside"
67
+ with(@foo) do
68
+ outter = get
69
+ end
70
+ assert( outter == @foo.get )
71
+ #this fails. unsure how / if it should stay as part of the spec
72
+ #problem is that (as far as I can tell) it will need to evaluate the post-transformation
73
+ #block in the original context, whereas it currently needs to be executed in a diff one
74
+ #this would be a lot easier - less transforms on other specs - if we could find the variable
75
+ #name of "@foo" within With.object
76
+ end
77
+
78
+ def test_With_works_with_assignment_to_outside_method_call_with_args
79
+ def f(x,y)
80
+ 398
81
+ end
82
+ with(@foo) do
83
+ a = f(1,3)
84
+ end
85
+ assert(@foo.a == 398)
86
+ end
87
+
88
+ def test_With_works_with_method_call_with_args_using_non_literals
89
+ def f(x,y)
90
+ 398
91
+ end
92
+ x = 2
93
+ y = 5
94
+ with(@foo) do
95
+ a = f(x,y)
96
+ end
97
+ assert(@foo.a == 398)
98
+ end
99
+
100
+
101
+ end
data/test/with_test.rb ADDED
@@ -0,0 +1,103 @@
1
+ require '../lib/with'
2
+ require 'test/unit'
3
+ require 'foo'
4
+
5
+
6
+
7
+ class TestWith < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @foo = Foo.new
11
+ end
12
+
13
+ def test_With_works_with_attr_accessor_assignment
14
+ foo = Foo.new
15
+ With.object(foo) do
16
+ get = 'got!'
17
+ end
18
+ assert(foo.get == "got!")
19
+ end
20
+
21
+ def test_With_works_with_two_attr_accessor_assignments
22
+ # Seems strange, but one line blocks don't show up as blocks after running through ParseTree,
23
+ # so this exercises the more common case, whereas the previous test exercises the uncommon one.
24
+ With.object(@foo) do
25
+ get = 'got!'
26
+ a = 'b'
27
+ end
28
+ assert(@foo.get == "got!")
29
+ assert(@foo.a == "b")
30
+ end
31
+
32
+ def test_With_works_with_method_call_no_args
33
+ With.object(@foo) do
34
+ get = 'got!'
35
+ change
36
+ end
37
+ assert(@foo.a == "changed!")
38
+ end
39
+
40
+ def test_With_works_with_method_call_with_args
41
+ With.object @foo do
42
+ set("c", "d")
43
+ set("d", "e")
44
+ end
45
+ assert @foo.a == "d"
46
+ assert @foo.b == "e"
47
+ end
48
+
49
+ def test_With_ignores_calls_to_methods_where_foo_respond_to?_is_false
50
+ With.object(@foo) do
51
+ puts
52
+ end
53
+ assert( true )
54
+ end
55
+
56
+ def test_With_works_with_assignment_to_outside_method_call_no_args
57
+ def outter
58
+ 5
59
+ end
60
+ With.object(@foo) do
61
+ a = outter
62
+ end
63
+
64
+ assert(@foo.a == 5)
65
+ end
66
+
67
+ def test_With_works_with_assignment_to_outside_lvar
68
+ outter = "outside"
69
+ With.object(@foo) do
70
+ outter = get
71
+ end
72
+ assert( outter == @foo.get )
73
+ #this fails. unsure how / if it should stay as part of the spec
74
+ #problem is that (as far as I can tell) it will need to evaluate the post-transformation
75
+ #block in the original context, whereas it currently needs to be executed in a diff one
76
+ #this would be a lot easier - less transforms on other specs - if we could find the variable
77
+ #name of "@foo" within With.object
78
+ end
79
+
80
+ def test_With_works_with_assignment_to_outside_method_call_with_args
81
+ def f(x,y)
82
+ 398
83
+ end
84
+ With.object(@foo) do
85
+ a = f(1,3)
86
+ end
87
+ assert(@foo.a == 398)
88
+ end
89
+
90
+ def test_With_works_with_method_call_with_args_using_non_literals
91
+ def f(x,y)
92
+ 398
93
+ end
94
+ x = 2
95
+ y = 5
96
+ With.object(@foo) do
97
+ a = f(x,y)
98
+ end
99
+ assert(@foo.a == 398)
100
+ end
101
+
102
+
103
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: codeodor-with
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sammy Larbi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-12 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.2.3
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: hoe
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 1.8.0
32
+ version:
33
+ description: "I sometimes get a little descriptive with my variable names, so when you're doing a lot of work specifically with one object, it gets especially ugly and repetetive, making the code harder to read than it needs to be: @contract_participants_on_drugs.contract_id = params[:contract_id] @contract_participants_on_drugs.participant_name = params[:participant_name] @contract_participants_on_drugs.drug_conviction = DrugConvictions.find(:wtf => 'this is getting ridiculous') ... And so on. It gets ridiculous. Utility Belt implements a with(object) method via a change to Object: class Object #utility belt implementation def with(object, &block) object.instance_eval &block end end Unfortunately, that just executes the block in the context of the object, so there isn't any crossover, nor can you perform assignments with attr_accessors (that I was able to do, anyway). So, here's With.object() to fill the void. With.object(@foo) do a = \"wtf\" b = \"this is not as bad\" end In the above example, @foo.a and @foo.b are the variables getting set. If you prefer, you can require 'with_on_object' instead and use the notation with(object) do ... end. The tests in the /test directory offer more examples of what's been implemented and tested so far (except where noted - namely performing assignment to a variable that was declared outside the block, and is not on @foo). Not everything is working yet, but it works for the simplest, most common cases I've run up against. More complex tests are on the way, along with code to make them pass. Special thanks to Reg Braithwaite, for help and ideas along the way."
34
+ email:
35
+ - sam@codeodor.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - History.txt
42
+ - Manifest.txt
43
+ - PostInstall.txt
44
+ - README.rdoc
45
+ files:
46
+ - History.txt
47
+ - Manifest.txt
48
+ - PostInstall.txt
49
+ - README
50
+ - README.rdoc
51
+ - Rakefile
52
+ - lib/with.rb
53
+ - lib/with_on_object.rb
54
+ - lib/with_sexp_processor.rb
55
+ - script/console
56
+ - script/destroy
57
+ - script/generate
58
+ - test/foo.rb
59
+ - test/test_helper.rb
60
+ - test/test_with.rb
61
+ - test/with_on_object_test.rb
62
+ - test/with_test.rb
63
+ - with.tmproj
64
+ has_rdoc: true
65
+ homepage: http://github.com/codeodor/with/tree/master
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --main
69
+ - README
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project: with
87
+ rubygems_version: 1.2.0
88
+ signing_key:
89
+ specification_version: 2
90
+ summary: "I sometimes get a little descriptive with my variable names, so when you're doing a lot of work specifically with one object, it gets especially ugly and repetetive, making the code harder to read than it needs to be: @contract_participants_on_drugs.contract_id = params[:contract_id] @contract_participants_on_drugs.participant_name = params[:participant_name] @contract_participants_on_drugs.drug_conviction = DrugConvictions.find(:wtf => 'this is getting ridiculous') .."
91
+ test_files:
92
+ - test/test_helper.rb
93
+ - test/test_with.rb