maroon 0.6.1 → 0.6.5

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/Examples/Dijkstra/CalculateShortestDistance.rb +16 -12
  3. data/Examples/Dijkstra/calculate_shortest_path.rb +47 -27
  4. data/Examples/Dijkstra/data.rb +41 -14
  5. data/Examples/Dijkstra/dijkstra.rb +4 -3
  6. data/Examples/MoneyTransfer.rb +61 -60
  7. data/Examples/greeter.rb +8 -7
  8. data/Examples/meter.rb +35 -29
  9. data/Gemfile +9 -4
  10. data/LICENSE.txt +21 -21
  11. data/README.md +13 -0
  12. data/Rakefile +41 -1
  13. data/Test/Generate/method_info_test.rb +12 -0
  14. data/Test/{Greeter_test.rb → Greeter_test_disabled.rb} +24 -20
  15. data/Test/ImmutableQueue_test.rb +18 -0
  16. data/Test/MethodInfo_test.rb +65 -0
  17. data/Test/alltests.rb +1 -0
  18. data/Test/{source_assertions.rb → assertions.rb} +15 -7
  19. data/Test/bind_test.rb +13 -0
  20. data/Test/expression_test.rb +105 -0
  21. data/Test/method_call_test.rb +83 -0
  22. data/Test/self_test.rb +46 -0
  23. data/Test/stack_test.rb +17 -0
  24. data/Test/test_helper.rb +14 -0
  25. data/base/ImmutableStack.rb +32 -0
  26. data/base/MethodDefinition.rb +124 -0
  27. data/base/bind_rewriter.rb +58 -0
  28. data/base/immutable_queue.rb +50 -0
  29. data/base/maroon_base.rb +267 -0
  30. data/base/method_call.rb +78 -0
  31. data/base/method_info.rb +86 -0
  32. data/base/self.rb +60 -0
  33. data/generated/build.rb +13 -0
  34. data/generated/interpretation_context.rb +29 -0
  35. data/lib/Bind.rb +65 -0
  36. data/lib/Context.rb +187 -0
  37. data/lib/ImmutableQueue.rb +50 -0
  38. data/lib/ImmutableStack.rb +38 -0
  39. data/lib/MethodCall.rb +91 -0
  40. data/lib/MethodDefinition.rb +114 -0
  41. data/lib/MethodInfo.rb +78 -0
  42. data/lib/Self.rb +71 -0
  43. data/lib/build.rb +14 -0
  44. data/lib/interpretation_context.rb +30 -0
  45. data/lib/maroon/contracts.rb +43 -0
  46. data/lib/maroon/kernel.rb +2 -0
  47. data/lib/maroon/version.rb +3 -3
  48. data/maroon.gemspec +26 -26
  49. metadata +49 -31
  50. data/lib/Source_cleaner.rb +0 -34
  51. data/lib/maroon.rb +0 -165
  52. data/lib/rewriter.rb +0 -185
@@ -1,3 +1,5 @@
1
+ require_relative '../Context'
2
+
1
3
  module Kernel
2
4
  def context(*args, &b)
3
5
  Context::define *args, &b
@@ -1,3 +1,3 @@
1
- module Maroon
2
- VERSION = '0.6.1'
3
- end
1
+ module Maroon
2
+ VERSION = '0.6.5'
3
+ end
@@ -1,26 +1,26 @@
1
- # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'maroon/version'
5
-
6
- Gem::Specification.new do |gem|
7
- gem.name = 'maroon'
8
- gem.version = Maroon::VERSION
9
- gem.authors = ['Rune Funch Søltoft']
10
- gem.email = %w(funchsoltoft@gmail.com)
11
- gem.description = %q{maroon makes DCI a DSL for Ruby it's mainly based on the work gone into Marvin,
12
- the first language to support injectionless DCI.
13
-
14
- The performance of code written using maroon is on par with code using regular method invocation.
15
-
16
- For examples on how to use maroon look at the examples found at the home page}
17
- gem.summary = %q{maroon}
18
- gem.homepage = 'https://github.com/runefs/maroon'
19
-
20
- gem.files = `git ls-files`.split($/)
21
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
22
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
- gem.require_paths = ["lib"]
24
- gem.add_runtime_dependency 'sourcify', '~>0.3', '>=0.3.10'
25
- gem.add_runtime_dependency 'sorcerer'
26
- end
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'maroon/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'maroon'
8
+ gem.version = Maroon::VERSION
9
+ gem.authors = ['Rune Funch Søltoft']
10
+ gem.email = %w(funchsoltoft@gmail.com)
11
+ gem.description = %q{maroon makes DCI a DSL for Ruby it's mainly based on the work gone into Marvin,
12
+ the first language to support injectionless DCI.
13
+
14
+ The performance of code written using maroon is on par with code using regular method invocation.
15
+
16
+ For examples on how to use maroon look at the examples found at the home page}
17
+ gem.summary = %q{maroon}
18
+ gem.homepage = 'https://github.com/runefs/Moby'
19
+
20
+ gem.files = `git ls-files`.split($/)
21
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
22
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
23
+ gem.require_paths = ["lib"]
24
+ gem.add_runtime_dependency 'sourcify', '~>0.3', '>=0.3.10'
25
+ gem.add_runtime_dependency 'sorcerer'
26
+ end
metadata CHANGED
@@ -1,65 +1,56 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maroon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
5
- prerelease:
4
+ version: 0.6.5
6
5
  platform: ruby
7
6
  authors:
8
7
  - Rune Funch Søltoft
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-27 00:00:00.000000000 Z
11
+ date: 2013-04-09 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: sourcify
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0.3'
22
- - - ! '>='
20
+ - - '>='
23
21
  - !ruby/object:Gem::Version
24
22
  version: 0.3.10
25
23
  type: :runtime
26
24
  prerelease: false
27
25
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
26
  requirements:
30
27
  - - ~>
31
28
  - !ruby/object:Gem::Version
32
29
  version: '0.3'
33
- - - ! '>='
30
+ - - '>='
34
31
  - !ruby/object:Gem::Version
35
32
  version: 0.3.10
36
33
  - !ruby/object:Gem::Dependency
37
34
  name: sorcerer
38
35
  requirement: !ruby/object:Gem::Requirement
39
- none: false
40
36
  requirements:
41
- - - ! '>='
37
+ - - '>='
42
38
  - !ruby/object:Gem::Version
43
39
  version: '0'
44
40
  type: :runtime
45
41
  prerelease: false
46
42
  version_requirements: !ruby/object:Gem::Requirement
47
- none: false
48
43
  requirements:
49
- - - ! '>='
44
+ - - '>='
50
45
  - !ruby/object:Gem::Version
51
46
  version: '0'
52
- description: ! 'maroon makes DCI a DSL for Ruby it''s mainly based on the work gone
53
- into Marvin,
54
-
47
+ description: |-
48
+ maroon makes DCI a DSL for Ruby it's mainly based on the work gone into Marvin,
55
49
  the first language to support injectionless DCI.
56
50
 
51
+ The performance of code written using maroon is on par with code using regular method invocation.
57
52
 
58
- The performance of code written using maroon is on par with code using regular method
59
- invocation.
60
-
61
-
62
- For examples on how to use maroon look at the examples found at the home page'
53
+ For examples on how to use maroon look at the examples found at the home page
63
54
  email:
64
55
  - funchsoltoft@gmail.com
65
56
  executables: []
@@ -78,36 +69,63 @@ files:
78
69
  - LICENSE.txt
79
70
  - README.md
80
71
  - Rakefile
81
- - Test/Greeter_test.rb
82
- - Test/source_assertions.rb
83
- - lib/Source_cleaner.rb
84
- - lib/maroon.rb
72
+ - Test/Generate/method_info_test.rb
73
+ - Test/Greeter_test_disabled.rb
74
+ - Test/ImmutableQueue_test.rb
75
+ - Test/MethodInfo_test.rb
76
+ - Test/alltests.rb
77
+ - Test/assertions.rb
78
+ - Test/bind_test.rb
79
+ - Test/expression_test.rb
80
+ - Test/method_call_test.rb
81
+ - Test/self_test.rb
82
+ - Test/stack_test.rb
83
+ - Test/test_helper.rb
84
+ - base/ImmutableStack.rb
85
+ - base/MethodDefinition.rb
86
+ - base/bind_rewriter.rb
87
+ - base/immutable_queue.rb
88
+ - base/maroon_base.rb
89
+ - base/method_call.rb
90
+ - base/method_info.rb
91
+ - base/self.rb
92
+ - generated/build.rb
93
+ - generated/interpretation_context.rb
94
+ - lib/Bind.rb
95
+ - lib/Context.rb
96
+ - lib/ImmutableQueue.rb
97
+ - lib/ImmutableStack.rb
98
+ - lib/MethodCall.rb
99
+ - lib/MethodDefinition.rb
100
+ - lib/MethodInfo.rb
101
+ - lib/Self.rb
102
+ - lib/build.rb
103
+ - lib/interpretation_context.rb
104
+ - lib/maroon/contracts.rb
85
105
  - lib/maroon/kernel.rb
86
106
  - lib/maroon/version.rb
87
- - lib/rewriter.rb
88
107
  - maroon.gemspec
89
- homepage: https://github.com/runefs/maroon
108
+ homepage: https://github.com/runefs/Moby
90
109
  licenses: []
110
+ metadata: {}
91
111
  post_install_message:
92
112
  rdoc_options: []
93
113
  require_paths:
94
114
  - lib
95
115
  required_ruby_version: !ruby/object:Gem::Requirement
96
- none: false
97
116
  requirements:
98
- - - ! '>='
117
+ - - '>='
99
118
  - !ruby/object:Gem::Version
100
119
  version: '0'
101
120
  required_rubygems_version: !ruby/object:Gem::Requirement
102
- none: false
103
121
  requirements:
104
- - - ! '>='
122
+ - - '>='
105
123
  - !ruby/object:Gem::Version
106
124
  version: '0'
107
125
  requirements: []
108
126
  rubyforge_project:
109
- rubygems_version: 1.8.24
127
+ rubygems_version: 2.0.0
110
128
  signing_key:
111
- specification_version: 3
129
+ specification_version: 4
112
130
  summary: maroon
113
131
  test_files: []
@@ -1,34 +0,0 @@
1
- require 'sourcify'
2
- require 'sorcerer'
3
-
4
- module Source_cleaner
5
- private
6
-
7
- #cleans up the string for further processing and separates arguments from body
8
- def block2source(method_name, &block)
9
- source = block.to_sexp
10
- raise 'unknown format' unless source[0] == :iter or source.length != 4
11
- args = get_args source[2]
12
- body = source[3]
13
- return args, body
14
- end
15
-
16
- def get_args(sexp)
17
- return nil unless sexp
18
- return sexp[1] if sexp[0] == :lasgn
19
- sexp = sexp[1][1..-1] # array or arguments
20
- args = []
21
- sexp.each { |e|
22
- args << e[1]
23
- }
24
- args.join(',')
25
- end
26
-
27
- def lambda2method (method_name, method)
28
- arguments, body = method.arguments, method.body
29
- transform_ast body
30
- block = Ruby2Ruby.new.process(body)
31
- args = "(#{arguments})" if arguments
32
- "\ndef #{method_name} #{args}\n#{block} end\n"
33
- end
34
- end
@@ -1,165 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require './lib/Source_cleaner.rb'
3
- require './lib/rewriter.rb'
4
-
5
-
6
- class Method_info
7
- def initialize(arguments,body)
8
- @arguments = arguments
9
- @body = body
10
- end
11
- attr_reader :arguments
12
- attr_reader :body
13
- end
14
-
15
- ##
16
- # The Context class is used to define a DCI context with roles and their role methods
17
- # to define a context call define with the name of the context (this name will become the name of the class that defines the context)
18
- # the name should be a symbol and since it's going to be used as a class name, use class naming conventions
19
- # follow the name with a block. With in this block you can define roles and interactions
20
- # and interaction is defined by write the name of the interaction (hello in the below example) followed by a block
21
- # the block will become the method body
22
- # a role can be defined much like a context. instead of calling the define method call the role method followed by the role name (as a symbol)
23
- # the role will be used for a private instance variable and the naming convention should match this
24
- # With in the block supplied to the role method you can define role methods the same way as you define interactions. See the method who
25
- # in the below example
26
- # = Example
27
- # Context::define :Greeter do
28
- # role :who do
29
- # say do
30
- # @who #could be self as well to refer to the current role player of the 'who' role
31
- # end
32
- # end
33
- # greeting do
34
- # p "Hello #{who.say}!"
35
- # end
36
- # end
37
- #
38
- # class Greeter
39
- # def initialize(player)
40
- # #@who = player
41
- # end
42
- # end
43
- #
44
- # Greeter.new('world').greeting #Will print "Hello world!"
45
- #maroon is base on Marvin which was the first injectionless language for DCI
46
- #being injectionless there's no runtime extend or anything else impacting the performance. There' only regular method invocation even when using role methods
47
- #Author:: Rune Funch Søltoft (funchsoltoft@gmail.com)
48
- #License:: Same as for Ruby
49
- ##
50
- class Context
51
- include Rewriter,Source_cleaner
52
- @roles
53
- @interactions
54
- @defining_role
55
- @role_alias
56
- @alias_list
57
- @cached_roles_and_alias_list
58
-
59
- #define is the only exposed method and can be used to define a context (class)
60
- #if maroon/kernel is required calling context of Context::define are equivalent
61
- #params
62
- #name:: the name of the context. Since this is used as the name of a class, class naming convetions should be used
63
- #block:: the body of the context. Can include definitions of roles (through the role method) or definitions of interactions
64
- #by simply calling a method with the name of the interaction and passing a block as the body of the interaction
65
- def self.define(*args, &block)
66
- name,base_class,default_interaction = *args
67
- #if there's two arguments and the second is not a class it must be an interaction
68
- if default_interaction && (!base_class.instance_of? Class) then base_class = eval(base_class.to_s) end
69
- base_class,default_interaction = default_interaction, base_class if base_class and !default_interaction and !base_class.instance_of? Class
70
- ctx = Context.new
71
- ctx.instance_eval &block
72
- return ctx.send(:finalize, name,base_class,default_interaction)
73
- end
74
-
75
- private
76
- ##
77
- #Defines a role with the given name
78
- #role methods can be defined inside a block passed to this method
79
- # = Example
80
- # role :who do
81
- # say do
82
- # p @who
83
- # end
84
- # end
85
- #The above code defines a role called 'who' with a role method called say
86
- ##
87
- def role(role_name)
88
- raise 'Argument role_name must be a symbol' unless role_name.instance_of? Symbol
89
-
90
- @defining_role = role_name
91
- @roles[role_name] = Hash.new
92
- yield if block_given?
93
- @defining_role = nil
94
- end
95
-
96
- def initialize
97
- @roles = Hash.new
98
- @interactions = Hash.new
99
- @role_alias = Array.new
100
- end
101
-
102
- def methods
103
- (@defining_role ? @roles[@defining_role] : @interactions)
104
- end
105
-
106
- def finalize(name, base_class, default)
107
- c = base_class ? (Class.new base_class) : Class.new
108
- Kernel.const_set name, c
109
- code = ''
110
- fields = ''
111
- getters = ''
112
- impl = ''
113
- interactions = ''
114
- @interactions.each do |method_name, method|
115
- @defining_role = nil
116
- interactions << " #{lambda2method(method_name, method)}"
117
- end
118
- if default
119
- interactions <<"
120
- def self.call(*args)
121
- arity =#{name}.method(:new).arity
122
- newArgs = args[0..arity-1]
123
- p \"new \#{newArgs}\"
124
- obj = #{name}.new *newArgs
125
- if arity < args.length
126
- methodArgs = args[arity..-1]
127
- p \"method \#{methodArgs}\"
128
- obj.#{default} *methodArgs
129
- else
130
- obj.#{default}
131
- end
132
- end
133
- "
134
- interactions <<"\ndef call(*args);#{default} *args; end\n"
135
- end
136
-
137
- @roles.each do |role, methods|
138
- fields << "@#{role}\n"
139
- getters << "def #{role};@#{role} end\n"
140
-
141
- methods.each do |method_name, method_source|
142
- @defining_role = role
143
- rewritten_method_name = "self_#{role}_#{method_name}"
144
- definition = lambda2method rewritten_method_name, method_source
145
- impl << " #{definition}" if definition
146
- end
147
- end
148
-
149
- code << "#{interactions}\n#{fields}\n private\n#{getters}\n#{impl}\n"
150
-
151
- complete = "class #{name}\r\n#{code}\r\nend"
152
- #File.open("#{name}_generated.rb", 'w') {|f| f.write(complete) }
153
- temp = c.class_eval(code)
154
- return (temp ||c),complete
155
- end
156
-
157
- def role_or_interaction_method(method_name,*args, &b)
158
- raise "method with out block #{method_name}" unless b
159
-
160
- args, body = block2source method_name, &b
161
- methods[method_name] = Method_info.new args,body
162
- end
163
-
164
- alias method_missing role_or_interaction_method
165
- end
@@ -1,185 +0,0 @@
1
- require 'Ripper'
2
-
3
- module Rewriter
4
- private
5
- def role_aliases
6
- @alias_list if @alias_list
7
- @alias_list = Hash.new
8
- @role_alias.each { |aliases|
9
- aliases.each { |k, v|
10
- @alias_list[k] = v
11
- }
12
- }
13
- @alias_list
14
- end
15
-
16
- def roles
17
- @cached_roles_and_alias_list if @cached_roles_and_alias_list
18
- @roles unless @role_alias and @role_alias.length
19
- @cached_roles_and_alias_list = Hash.new
20
- @roles.each { |k, v|
21
- @cached_roles_and_alias_list[k] = v
22
- }
23
- role_aliases.each { |k, v|
24
- @cached_roles_and_alias_list[k] = @roles[v]
25
- }
26
- @cached_roles_and_alias_list
27
- end
28
-
29
- def add_alias (a, role_name)
30
- @cached_roles_and_alias_list, @alias_list = nil
31
- @role_alias.last()[a] = role_name
32
- end
33
-
34
- def role_method_call(ast, method)
35
- is_call_expression = ast && ast[0] == :call
36
- self_is_instance_expression = is_call_expression && (!ast[1]) #implicit self
37
- is_in_block = ast && ast[0] == :lvar
38
- role_name_index = self_is_instance_expression ? 2 : 1
39
- role = (self_is_instance_expression || is_in_block) ? roles[ast[role_name_index]] : nil #is it a call to a role getter
40
- is_role_method = role && role.has_key?(method)
41
- role_name = is_in_block ? role_aliases[ast[1]] : (ast[2] if self_is_instance_expression)
42
- role_name if is_role_method #return role name
43
- end
44
-
45
- ##
46
- #Test if there's a block that needs to potentially be transformed
47
- ##
48
- def transform_block(exp)
49
- if exp && exp[0] == :iter
50
- (exp.length-1).times do |i|
51
- expr = exp[i+1]
52
- #find the block
53
- if expr && expr.length && expr[0] == :block
54
- transform_ast exp if rewrite_bind? expr, expr[1]
55
- end
56
- end
57
- end
58
- end
59
-
60
- ##
61
- #Calls rewrite_block if needed and will return true if the AST was changed otherwise false
62
- ##
63
- def rewrite_bind?(block, expr)
64
- changed = false
65
- #check if the first call is a bind call
66
- if expr && expr.length && (expr[0] == :call && expr[1] == nil && expr[2] == :bind)
67
- argument_list = expr[3]
68
- if argument_list && argument_list[0] == :arglist
69
- arguments = argument_list[1]
70
- if arguments && arguments[0] == :hash
71
- block.delete_at 1
72
- count = (arguments.length-1) / 2
73
- (1..count).each do |j|
74
- temp = j * 2
75
- local = arguments[temp-1][1]
76
- if local.instance_of? Sexp
77
- local = local[1]
78
- end
79
- raise 'invalid value for role alias' unless local.instance_of? Symbol
80
- #find the name of the role being bound to
81
- aliased_role = arguments[temp][1]
82
- if aliased_role.instance_of? Sexp
83
- aliased_role = aliased_role[1]
84
- end
85
- raise "#{aliased_role} used in binding is an unknown role #{roles}" unless aliased_role.instance_of? Symbol and @roles.has_key? aliased_role
86
- add_alias local, aliased_role
87
- #replace bind call with assignment of iteration variable to role field
88
- do_rewrite_bind(aliased_role, local, block)
89
- changed = true
90
- end
91
- end
92
- end
93
- end
94
- changed
95
- end
96
-
97
- ##
98
- #removes call to bind in a block
99
- #and replaces it with assignment to the proper role player local variables
100
- #in the end of the block the local variables have their original values reassigned
101
- def do_rewrite_bind(aliased_role, local, block)
102
- raise 'aliased_role must be a Symbol' unless aliased_role.instance_of? Symbol
103
- raise 'local must be a Symbol' unless local.instance_of? Symbol
104
- aliased_field = "@#{aliased_role}".to_sym
105
- assignment = Sexp.new
106
- assignment[0] = :iasgn
107
- assignment[1] = aliased_field
108
- load_arg = Sexp.new
109
- load_arg[0] = :lvar
110
- load_arg[1] = local
111
- assignment[2] = load_arg
112
- block.insert 1, assignment
113
-
114
- # assign role player to temp
115
- temp_symbol = "temp____#{aliased_role}".to_sym
116
- assignment = Sexp.new
117
- assignment[0] = :lasgn
118
- assignment[1] = temp_symbol
119
- load_field = Sexp.new
120
- load_field[0] = :ivar
121
- load_field[1] = aliased_field
122
- assignment[2] = load_field
123
- block.insert 1, assignment
124
-
125
- # reassign original player
126
- assignment = Sexp.new
127
- assignment[0] = :iasgn
128
- assignment[1] = aliased_field
129
- load_temp = Sexp.new
130
- load_temp[0] = :lvar
131
- load_temp[1] = temp_symbol
132
- assignment[2] = load_temp
133
- block[block.length] = assignment
134
- end
135
-
136
- # rewrites a call to self in a role method to a call to the role player accessor
137
- # which is subsequently rewritten to a call to the instance variable itself
138
- # in the case where no role method is called on the role player
139
- # It's rewritten to an instance call on the context object if a role method is called
140
- def rewrite_self (ast)
141
- ast.length.times do |i|
142
- raise 'Invalid argument. must be an expression' unless ast.instance_of? Sexp
143
- exp = ast[i]
144
- if exp == :self
145
- ast[0] = :call
146
- ast[1] = nil
147
- ast[2] = @defining_role
148
- arglist = Sexp.new
149
- ast[3] = arglist
150
- arglist[0] = :arglist
151
- elsif exp.instance_of? Sexp
152
- rewrite_self exp
153
- end
154
- end
155
- end
156
-
157
- #rewrites the ast so that role method calls are rewritten to a method invocation on the context object rather than the role player
158
- #also does rewriting of binds in blocks
159
- def transform_ast(ast)
160
- if ast
161
- if @defining_role
162
- rewrite_self ast
163
- end
164
- ast.length.times do |k|
165
- exp = ast[k]
166
- if exp
167
- method_name = exp[2]
168
- role = role_method_call exp[1], exp[2]
169
- if exp[0] == :iter
170
- @role_alias.push Hash.new
171
- transform_block exp
172
- @role_alias.pop()
173
- end
174
- if exp[0] == :call && role
175
- exp[1] = nil #remove call to attribute
176
- exp[2] = "self_#{role}_#{method_name}".to_sym
177
- end
178
- if exp.instance_of? Sexp
179
- transform_ast exp
180
- end
181
- end
182
- end
183
- end
184
- end
185
- end