Class: Innate::Action
- Inherits:
-
Struct
- Object
- Struct
- Innate::Action
- Defined in:
- lib/innate/action.rb
Constant Summary collapse
- COPY_VARIABLES =
' STATE[:action_variables].each do |iv, value| instance_variable_set("@#{iv}", value) end'.strip.freeze
Class Method Summary collapse
-
.create(hash = {}) ⇒ Action
Create a new Action instance.
Instance Method Summary collapse
-
#binding ⇒ Binding
Binding of the instance for this Action.
-
#call ⇒ String
Call the Action instance, will insert itself temporarily into Current.actions during the render operation so even in nested calls one can still access all other Action instances.
-
#copy_variables(binding = self.binding) ⇒ NilClass
Copy Action#variables as instance variables into the given binding.
- #layout_view_or_method(name, arg) ⇒ Object
- #merge!(hash) ⇒ Object
-
#name ⇒ Object
Try to figure out a sane name for current action.
- #render ⇒ Object
-
#sync_variables(from_action) ⇒ Action
Copy the instance variable names and values from given from_action#instance into the Action#variables of the action this method is called on.
- #valid? ⇒ Boolean
- #wrap_in_layout ⇒ Object
Class Method Details
.create(hash = {}) ⇒ Action
Create a new Action instance. Note that the default cannot be a constant as assigning the value objects to the struct would modify them and might lead to bugs due to persisting action contents.
15 16 17 18 |
# File 'lib/innate/action.rb', line 15 def self.create(hash = {}) default = {:options => {}, :variables => {}, :params => []} new(*default.merge(hash.to_hash).values_at(*ACTION_MEMBERS)) end |
Instance Method Details
#binding ⇒ Binding
Returns binding of the instance for this Action.
45 46 47 |
# File 'lib/innate/action.rb', line 45 def binding instance.binding end |
#call ⇒ String
Call the Action instance, will insert itself temporarily into Current.actions during the render operation so even in nested calls one can still access all other Action instances. Will initialize the assigned node and call Action#render
34 35 36 37 38 39 |
# File 'lib/innate/action.rb', line 34 def call Current.actions << self render ensure Current.actions.delete(self) end |
#copy_variables(binding = self.binding) ⇒ NilClass
Copy Action#variables as instance variables into the given binding.
This relies on Innate::STATE, so should be thread-safe and doesn’t depend on Innate::Current::actions order. So we avoid nasty business with Objectspace#_id2ref which may not work on all ruby implementations and seems to cause other problems as well.
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/innate/action.rb', line 86 def copy_variables(binding = self.binding) return unless variables.any? STATE.sync do STATE[:action_variables] = self.variables eval(COPY_VARIABLES, binding) STATE[:action_variables] = nil end end |
#layout_view_or_method(name, arg) ⇒ Object
127 128 129 |
# File 'lib/innate/action.rb', line 127 def layout_view_or_method(name, arg) [:layout, :view].include?(name) ? [arg, nil] : [nil, arg] end |
#merge!(hash) ⇒ Object
20 21 22 23 |
# File 'lib/innate/action.rb', line 20 def merge!(hash) hash.each_pair{|key, value| send("#{key}=", value) } self end |
#name ⇒ Object
Try to figure out a sane name for current action.
132 133 134 |
# File 'lib/innate/action.rb', line 132 def name File.basename((method || view).to_s).split('.').first end |
#render ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/innate/action.rb', line 98 def render self.instance = node.new self.variables[:content] ||= nil instance.wrap_action_call(self) do copy_variables # this might need another position after all self.value = instance.__send__(method, *params) if method self.view_value = File.read(view) if view body, content_type = wrap_in_layout{ engine.call(self, view_value || value || '') } [:content_type] ||= content_type if content_type body end end |
#sync_variables(from_action) ⇒ Action
Copy the instance variable names and values from given from_action#instance into the Action#variables of the action this method is called on.
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/innate/action.rb', line 58 def sync_variables(from_action) instance = from_action.instance instance.instance_variables.each{|iv| iv_value = instance.instance_variable_get(iv) iv_name = iv.to_s[1..-1] self.variables[iv_name.to_sym] = iv_value } from_action end |
#valid? ⇒ Boolean
136 137 138 |
# File 'lib/innate/action.rb', line 136 def valid? method || view end |
#wrap_in_layout ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/innate/action.rb', line 114 def wrap_in_layout return yield unless layout action = dup action.view, action.method = layout_view_or_method(*layout) action.layout = nil action.view_value = nil action.sync_variables(self) body, content_type = yield action.variables[:content] = body return action.call, content_type end |