Class: Linecook::Recipe
- Inherits:
- BasicObject
- Defined in:
- lib/linecook/recipe.rb
Overview
Recipe is the context in which recipes are evaluated (literally). Recipe uses compiled ERB snippets to build text using method calls. For example:
module Helper
# This is an ERB template compiled to write to a Recipe.
#
# compiler = ERB::Compiler.new('<>')
# compiler.put_cmd = "write"
# compiler.insert_cmd = "write"
# compiler.compile("echo '<%= args.join(' ') %>'\n")
#
def echo(*args)
write "echo '"; write(( args.join(' ') ).to_s); write "'\n"
end
end
recipe = Recipe.new do
_extend_ Helper
echo 'a', 'b c'
echo 'X Y'.downcase, :z
end
"\n" + recipe.to_s
# => %{
# echo 'a b c'
# echo 'x y z'
# }
Instance Attribute Summary collapse
-
#_cookbook_ ⇒ Object
readonly
The recipe Cookbook.
-
#_package_ ⇒ Object
readonly
The recipe Package.
-
#_package_opts_ ⇒ Object
readonly
Returns the value of attribute package_opts.
-
#_package_path_ ⇒ Object
readonly
Returns the value of attribute package_path.
-
#_proxy_ ⇒ Object
readonly
The recipe Proxy.
-
#target ⇒ Object
readonly
The target recieving writes.
Class Method Summary collapse
-
.const_missing(name) ⇒ Object
Overridden to look up constants as normal.
Instance Method Summary collapse
-
#_(str = nil, &block) ⇒ Object
Returns a child of self with a new target.
-
#_beget_ ⇒ Object
Returns a clone of self created by clone, but also calls initialize_child on the clone.
-
#_class_ ⇒ Object
Returns the class for self.
-
#_clone_ ⇒ Object
Returns a clone of self, kind of like Object#clone.
-
#_extend_(mod) ⇒ Object
Extends self with the module.
-
#_initialize_child_(orig) ⇒ Object
Callback to initialize children created by beget.
-
#_initialize_clone_(orig) ⇒ Object
Callback to initialize a clone of self.
-
#_singleton_class_ ⇒ Object
Returns the singleton class for self.
-
#attributes(source_name = nil, &block) ⇒ Object
Loads the specified attributes file and merges the results into attrs.
-
#attrs ⇒ Object
Returns the package env merged over any attrs specified by attributes.
-
#capture(target = "") ⇒ Object
Captures writes during the block to a new target.
- #capture_to(package_path, options = {}) ⇒ Object
-
#chain ⇒ Object
Causes chain? to return true.
-
#chain? ⇒ Boolean
Returns true as per chain/unchain.
-
#chain_proxy ⇒ Object
Returns the proxy.
-
#helpers(*helper_names) ⇒ Object
Looks up and extends self with the specified helper(s).
-
#initialize(package = Package.new, cookbook = Cookbook.new, target = "") ⇒ Recipe
constructor
A new instance of Recipe.
- #register(package_path, options = {}) ⇒ Object
- #register_as(path, options = {}) ⇒ Object
- #register_to(package, path = _package_path_, options = _package_opts_) ⇒ Object
-
#render(template_name, locals = attrs) ⇒ Object
Looks up a template in cookbook and renders it.
-
#to_s ⇒ Object
Returns target.to_s.
-
#unchain ⇒ Object
Causes chain? to return false.
-
#write(input) ⇒ Object
Writes input to target using ‘<<`.
-
#writeln(input = nil) ⇒ Object
Writes input to self, writes a newline, and returns last.
Constructor Details
#initialize(package = Package.new, cookbook = Cookbook.new, target = "") ⇒ Recipe
Returns a new instance of Recipe.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/linecook/recipe.rb', line 55 def initialize(package = Package.new, cookbook = Cookbook.new, target = "") @_proxy_ = Proxy.new(self) @_package_ = package @_cookbook_ = cookbook @_package_path_ = nil @_package_opts_ = nil @target = target @chain = false @attributes = {} @attrs = nil if Kernel.block_given? instance_eval(&Proc.new) end end |
Instance Attribute Details
#_cookbook_ ⇒ Object (readonly)
The recipe Cookbook
50 51 52 |
# File 'lib/linecook/recipe.rb', line 50 def _cookbook_ @_cookbook_ end |
#_package_ ⇒ Object (readonly)
The recipe Package
43 44 45 |
# File 'lib/linecook/recipe.rb', line 43 def _package_ @_package_ end |
#_package_opts_ ⇒ Object (readonly)
Returns the value of attribute package_opts.
47 48 49 |
# File 'lib/linecook/recipe.rb', line 47 def _package_opts_ @_package_opts_ end |
#_package_path_ ⇒ Object (readonly)
Returns the value of attribute package_path.
45 46 47 |
# File 'lib/linecook/recipe.rb', line 45 def _package_path_ @_package_path_ end |
#_proxy_ ⇒ Object (readonly)
The recipe Proxy
40 41 42 |
# File 'lib/linecook/recipe.rb', line 40 def _proxy_ @_proxy_ end |
#target ⇒ Object (readonly)
The target recieving writes
53 54 55 |
# File 'lib/linecook/recipe.rb', line 53 def target @target end |
Class Method Details
.const_missing(name) ⇒ Object
Overridden to look up constants as normal.
72 73 74 |
# File 'lib/linecook/recipe.rb', line 72 def self.const_missing(name) ::Object.const_get(name) end |
Instance Method Details
#_(str = nil, &block) ⇒ Object
Returns a child of self with a new target. Writes str to the child, and evaluates the block in the context of the child, if given.
147 148 149 150 151 152 |
# File 'lib/linecook/recipe.rb', line 147 def _(str=nil, &block) child = _beget_ child.write str if str child.instance_eval(&block) if block child end |
#_beget_ ⇒ Object
Returns a clone of self created by clone, but also calls initialize_child on the clone.
139 140 141 142 143 |
# File 'lib/linecook/recipe.rb', line 139 def _beget_ clone = _clone_ clone._initialize_child_(self) clone end |
#_class_ ⇒ Object
Returns the class for self.
91 92 93 |
# File 'lib/linecook/recipe.rb', line 91 def _class_ _singleton_class_.superclass end |
#_clone_ ⇒ Object
Returns a clone of self, kind of like Object#clone.
Note that unlike Object.clone this currently does not carry forward tainted/frozen state, nor can it carry forward singleton methods. Modules and internal state only.
119 120 121 122 123 124 |
# File 'lib/linecook/recipe.rb', line 119 def _clone_ clone = _class_.allocate clone._initialize_clone_(self) _singleton_class_.included_modules.each {|mod| clone._extend_ mod } clone end |
#_extend_(mod) ⇒ Object
Extends self with the module.
96 97 98 |
# File 'lib/linecook/recipe.rb', line 96 def _extend_(mod) mod.__send__(:extend_object, self) end |
#_initialize_child_(orig) ⇒ Object
Callback to initialize children created by beget. Sets a new target by calling dup.clear on the original target, and unchains. Note that the child shares the same attributes as the parent, and so can (un)intentionally cause changes in the parent.
130 131 132 133 134 135 |
# File 'lib/linecook/recipe.rb', line 130 def _initialize_child_(orig) @target = orig.target.dup.clear @_package_path_ = nil @_package_opts_ = nil unchain end |
#_initialize_clone_(orig) ⇒ Object
Callback to initialize a clone of self. Passes forward all state, including local data and attributes.
102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/linecook/recipe.rb', line 102 def _initialize_clone_(orig) @_proxy_ = Proxy.new(self) @_package_ = orig._package_ @_cookbook_ = orig._cookbook_ @_package_path_ = orig._package_path_ @_package_opts_ = orig._package_path_ @target = orig.target @chain = orig.chain? @attributes = orig.attributes @attrs = nil end |
#_singleton_class_ ⇒ Object
Returns the singleton class for self. Used by clone to access modules included in self (ex via extend).
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/linecook/recipe.rb', line 78 def _singleton_class_ class << self SINGLETON_CLASS = self def _singleton_class_ SINGLETON_CLASS end end # this and future calls go to the _singleton_class_ as defined above. _singleton_class_ end |
#attributes(source_name = nil, &block) ⇒ Object
Loads the specified attributes file and merges the results into attrs. A block may be given to specify attrs as well; it will be evaluated in the context of an Attributes instance.
Returns a hash representing all attributes loaded thusfar (specifically attrs prior to merging in the package env). The attributes hash should be treated as if it were read-only.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/linecook/recipe.rb', line 171 def attributes(source_name=nil, &block) if source_name || block attributes = Attributes.new if source_name if source_path = _cookbook_.find(:attributes, source_name, attributes.load_attrs_extnames) attributes.load_attrs(source_path) end end if block attributes.instance_eval(&block) end @attributes = Utils.deep_merge(@attributes, attributes.to_hash) @attrs = nil end @attributes end |
#attrs ⇒ Object
Returns the package env merged over any attrs specified by attributes.
The attrs hash should be treated as if it were read-only because changes could alter the package env and thereby spill over into other recipes.
196 197 198 |
# File 'lib/linecook/recipe.rb', line 196 def attrs @attrs ||= Utils.deep_merge(@attributes, _package_.env) end |
#capture(target = "") ⇒ Object
Captures writes during the block to a new target. Returns the target.
224 225 226 227 228 229 230 231 232 233 |
# File 'lib/linecook/recipe.rb', line 224 def capture(target = "") current = @target begin @target = target yield ensure @target = current end target end |
#capture_to(package_path, options = {}) ⇒ Object
235 236 237 238 |
# File 'lib/linecook/recipe.rb', line 235 def capture_to(package_path, ={}) str = capture { yield } _package_.add(package_path, ) {|io| io << str } end |
#chain ⇒ Object
Causes chain? to return true. Returns self.
261 262 263 264 |
# File 'lib/linecook/recipe.rb', line 261 def chain @chain = true self end |
#chain? ⇒ Boolean
Returns true as per chain/unchain.
280 281 282 |
# File 'lib/linecook/recipe.rb', line 280 def chain? @chain end |
#chain_proxy ⇒ Object
Returns the proxy. Unchains first to ensure that if the proxy is not called, then the previous chain is stopped.
274 275 276 277 |
# File 'lib/linecook/recipe.rb', line 274 def chain_proxy unchain _proxy_ end |
#helpers(*helper_names) ⇒ Object
Looks up and extends self with the specified helper(s).
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/linecook/recipe.rb', line 201 def helpers(*helper_names) helper_names.each do |helper| unless helper.respond_to?(:extend_object) helper_name = helper module_name = Utils.camelize(helper_name) helper = Utils.constantize(module_name) do # Don't use Kernel because that may evade RubyGems Utils.__send__(:require, Utils.underscore(helper_name)) Utils.constantize(module_name) end end helper.__send__(:extend_object, self) end self end |
#register(package_path, options = {}) ⇒ Object
218 219 220 221 |
# File 'lib/linecook/recipe.rb', line 218 def register(package_path, ={}) source_path = _cookbook_.find(:files, [:source] || package_path) _package_.register(package_path, source_path, ) end |
#register_as(path, options = {}) ⇒ Object
154 155 156 157 158 |
# File 'lib/linecook/recipe.rb', line 154 def register_as(path, ={}) @_package_path_ = path @_package_opts_ = self end |
#register_to(package, path = _package_path_, options = _package_opts_) ⇒ Object
160 161 162 |
# File 'lib/linecook/recipe.rb', line 160 def register_to(package, path = _package_path_, = _package_opts_) package.add(path, ) {|io| io << to_s } end |
#render(template_name, locals = attrs) ⇒ Object
Looks up a template in cookbook and renders it.
255 256 257 258 |
# File 'lib/linecook/recipe.rb', line 255 def render(template_name, locals=attrs) file = _cookbook_.find(:templates, template_name, ['.erb']) Tilt.new(file).render(Object.new, locals) end |
#to_s ⇒ Object
Returns target.to_s.
285 286 287 |
# File 'lib/linecook/recipe.rb', line 285 def to_s target.to_s end |
#unchain ⇒ Object
Causes chain? to return false. Returns self.
267 268 269 270 |
# File 'lib/linecook/recipe.rb', line 267 def unchain @chain = false self end |
#write(input) ⇒ Object
Writes input to target using ‘<<`. Stringifies input using to_s. Returns self.
242 243 244 245 |
# File 'lib/linecook/recipe.rb', line 242 def write(input) target << input.to_s self end |
#writeln(input = nil) ⇒ Object
Writes input to self, writes a newline, and returns last.
248 249 250 251 252 |
# File 'lib/linecook/recipe.rb', line 248 def writeln(input=nil) write input write "\n" self end |