Class: Jsrb::ExprChain
- Inherits:
-
Object
- Object
- Jsrb::ExprChain
- Defined in:
- lib/jsrb/expr_chain.rb
Overview
ExprChain is a builder class that constructs JavaScript expressions in natural phrase by chaining methods.
Note that ExprChain does NOT add any statement to be rendered.
If you want to add the expression as an ExpressionStatement,
use Jsrb::Base#do!
:
js.do!(obj.foo = 100) # pushes a statement `obj.foo = 100;`.
# where `obj.foo = 100` is still a chainable ExprChain instance,
# so that we have to explicitly push it as statement with `js.do!`.
Constant Summary collapse
- JS_LOGICAL_OPS =
%w[&& ||].freeze
Class Method Summary collapse
-
.add_custom_chain(chain_method_name, function_name) ⇒ Object
Adds a new chain method.
Instance Method Summary collapse
-
#[](value) ⇒ Jsrb::ExprChain
Constructs a MemberExpression.
-
#call(*args) { ... } ⇒ Jsrb::ExprChain
Constructs a CallExpression.
-
#cond?(consequent, alternate) ⇒ Jsrb::ExprChain
Constructs a ConditionalExpression whose test expression is the current expression.
-
#forall(*args) ⇒ Jsrb::ExprChain
Constructs a FunctionExpression whose returned body is the current context.
-
#method_missing(name, *args, &block) ⇒ Object
Responds to arbitrary method names.
-
#new(*args) ⇒ Jsrb::ExprChain
Constructs a NewExpression.
-
#op(operator, *args) ⇒ Jsrb::ExprChain
Constructs a UnaryExpression, BinaryExpression or LogicalExpression.
-
#set(value) ⇒ Jsrb::ExprChain
Constructs a AssignmentExpression whose RHS is the current expression.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
Responds to arbitrary method names
62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/jsrb/expr_chain.rb', line 62 def method_missing(name, *args, &block) if (matches = name.to_s.match(/\A(.+)\?\z/)) self[matches[1]].cond?(*args) elsif (matches = name.to_s.match(/\A(.+)=\z/)) self[matches[1]].set(*args) elsif (function_name = self.class.custom_chains[name.to_sym]) _bind_chain!(function_name, *args, &block) elsif args.empty? && !block self[name.to_s] else self[name.to_s].call(*args, &block) end end |
Class Method Details
.add_custom_chain(chain_method_name, function_name) ⇒ Object
Adds a new chain method.
278 279 280 281 |
# File 'lib/jsrb/expr_chain.rb', line 278 def add_custom_chain(chain_method_name, function_name) @_custom_chains ||= {} @_custom_chains[chain_method_name] = function_name end |
Instance Method Details
#[](value) ⇒ Jsrb::ExprChain
Constructs a MemberExpression
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/jsrb/expr_chain.rb', line 84 def [](value) if @object self.class.new @context, type: 'MemberExpression', computed: true, object: @object, property: @context.ruby_to_js_ast(value) else self.class.new @context, type: 'Identifier', name: value.to_s end end |
#call(*args) { ... } ⇒ Jsrb::ExprChain
Constructs a CallExpression.
124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/jsrb/expr_chain.rb', line 124 def call(*args, &block) raise ArgumentError, "Can't chain call on empty context" unless @object js_args = args.map do |arg| @context.ruby_to_js_ast(arg) end js_args << @context.ruby_to_js_ast(block) if block self.class.new @context, type: 'CallExpression', callee: @object, arguments: js_args end |
#cond?(consequent, alternate) ⇒ Jsrb::ExprChain
Constructs a ConditionalExpression whose test expression is the current expression.
215 216 217 218 219 220 221 222 |
# File 'lib/jsrb/expr_chain.rb', line 215 def cond?(consequent, alternate) raise ArgumentError, "Can't chain cond? on empty context" unless @object self.class.new @context, type: 'ConditionalExpression', test: @object, consequent: @context.ruby_to_js_ast(consequent), alternate: @context.ruby_to_js_ast(alternate) end |
#forall(*args) ⇒ Jsrb::ExprChain
Constructs a FunctionExpression whose returned body is the current context.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/jsrb/expr_chain.rb', line 231 def forall(*args) raise ArgumentError, "Can't chain forall on empty context" unless @object self.class.new @context, type: 'FunctionExpression', id: nil, params: args.map { |arg| { type: 'Identifier', name: arg.to_s } }, body: { type: 'BlockStatement', body: [ { type: 'ReturnStatement', argument: @object } ] } end |
#new(*args) ⇒ Jsrb::ExprChain
Constructs a NewExpression.
144 145 146 147 148 149 150 151 152 153 |
# File 'lib/jsrb/expr_chain.rb', line 144 def new(*args) raise ArgumentError, "Can't chain new on empty context" unless @object arguments = args.map do |arg| @context.ruby_to_js_ast(arg) end self.class.new @context, type: 'NewExpression', callee: @object, arguments: arguments end |
#op(operator, *args) ⇒ Jsrb::ExprChain
Constructs a UnaryExpression, BinaryExpression or LogicalExpression.
All ruby-overridable operators can also be used:
** + - * / % >> << & ^ | <= < > >= == === != ! && ||
167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/jsrb/expr_chain.rb', line 167 def op(operator, *args) raise ArgumentError, "Can't chain op on empty context" unless @object opstr = operator.to_s if args.size == 1 _binary_op(opstr, *args) elsif args.empty? _unary_op(opstr) else raise ArgumentError, "#{opstr} is not a valid operator" end end |
#set(value) ⇒ Jsrb::ExprChain
Constructs a AssignmentExpression whose RHS is the current expression.
105 106 107 108 109 110 111 112 |
# File 'lib/jsrb/expr_chain.rb', line 105 def set(value) raise ArgumentError, "Can't chain set on empty context" unless @object self.class.new @context, type: 'AssignmentExpression', operator: '=', left: @object, right: @context.ruby_to_js_ast(value) end |