Class: RubyTransform::Transformers::Tapifier
- Inherits:
-
RubyTransform::Transformer
- Object
- RubyTransform::Transformer
- RubyTransform::Transformers::Tapifier
- Defined in:
- lib/ruby_transform/transformers/tapifier.rb
Overview
Method Temporary Variables to Tap Block
Looks for instances of method declarations where:
-
A local variable is assigned to something as the first statement.
-
As the last statement, that local variable is returned is expressed.
These instances of using “temporary variables” to construct something for returning can be more elegantly expressed by using the .tap idiom.
Example:
def my_method
temp = ""
temp << "Something"
call_something(temp)
temp
end
Converts To:
def my_method
"".tap do |temp|
temp << "Something"
call_something(temp)
end
end
Instance Method Summary collapse
- #expresses_local_variable?(e, local_variable) ⇒ Boolean
- #matches_block_to_use_tap?(e) ⇒ Boolean
- #matches_method_to_use_tap?(e) ⇒ Boolean
- #transform(e) ⇒ Object
- #transform_block_to_use_tap(e) ⇒ Object
- #transform_method_to_use_tap(e) ⇒ Object
- #transform_tapify_candidates(e) ⇒ Object
Methods included from RubyTransform::TransformerHelpers
Instance Method Details
#expresses_local_variable?(e, local_variable) ⇒ Boolean
56 57 58 59 |
# File 'lib/ruby_transform/transformers/tapifier.rb', line 56 def expresses_local_variable?(e, local_variable) (e.kind == :lvar && e.body[0] == local_variable) || (e.kind == :return && expresses_local_variable?(e.body[0], local_variable)) end |
#matches_block_to_use_tap?(e) ⇒ Boolean
48 49 50 51 52 53 54 |
# File 'lib/ruby_transform/transformers/tapifier.rb', line 48 def matches_block_to_use_tap?(e) return matches_block_to_use_tap?(e.body[0]) if e.body.size == 1 && e.body[0].kind == :block e.is_a?(Sexp) && e.kind == :block && # Some block (or method body) e.body[0].kind == :lasgn && # The first line assigns to a local variable expresses_local_variable?(e.body[-1], e.body[0].body[0]) end |
#matches_method_to_use_tap?(e) ⇒ Boolean
43 44 45 46 |
# File 'lib/ruby_transform/transformers/tapifier.rb', line 43 def matches_method_to_use_tap?(e) e.is_a?(Sexp) && [:defn, :defs].include?(e.kind) && matches_block_to_use_tap?(e.body[2]) end |
#transform(e) ⇒ Object
31 32 33 |
# File 'lib/ruby_transform/transformers/tapifier.rb', line 31 def transform(e) super(transform_tapify_candidates(e)) end |
#transform_block_to_use_tap(e) ⇒ Object
65 66 67 68 69 70 71 72 73 |
# File 'lib/ruby_transform/transformers/tapifier.rb', line 65 def transform_block_to_use_tap(e) return s(:scope, transform_block_to_use_tap(e.body[0])) if e.body.size == 1 && e.kind == :scope && e.body[0].kind == :block s(:block, s(:iter, s(:call, e.body[0].body[1], :tap, s(:arglist)), s(:lasgn, e.body[0].body[0]), s(*([:block] + e.body[1..-2])) )) end |
#transform_method_to_use_tap(e) ⇒ Object
61 62 63 |
# File 'lib/ruby_transform/transformers/tapifier.rb', line 61 def transform_method_to_use_tap(e) s(e.kind, e.body[0], e.body[1], transform_block_to_use_tap(e.body[2])) end |
#transform_tapify_candidates(e) ⇒ Object
35 36 37 38 39 40 41 |
# File 'lib/ruby_transform/transformers/tapifier.rb', line 35 def transform_tapify_candidates(e) if matches_method_to_use_tap?(e) transform_method_to_use_tap(e) else e end end |