-
Notifications
You must be signed in to change notification settings - Fork 57
swineherd making scripts autorun
Some metaprogramming tips:
http://apidock.com/rails/Object/instance_exec
http://ruby.runpaint.org/methods#dynamic-definition
define_singleton_method(:call, *proc)
http://www.ruby-doc.org/core-1.9.3/Proc.html#method-i-curry
class ClassAttributeHandler < YARD::Handlers::Ruby::AttributeHandler
handles method_call(:cattr_accessor)
namespace_only
def process
push_state(:scope => :class) { super }
end
end
http://www.tutorialspoint.com/ruby/ruby_blocks.htm
BEGIN and END Blocks Every Ruby source file can declare blocks of code to be run as the file is being loaded (the BEGIN blocks) and after the program has finished executing (the END blocks).
BEGIN { begin block code }
END { end block code }
A program may include multiple BEGIN and END blocks. BEGIN blocks are executed in the order they are encountered. END blocks are executed in reverse order.
(from Read Ruby
A begin or exit handler registers code to be executed at the beginning or end, respectively, of a program.
A BEGIN block, as opposed to a begin statement, is executed at the very beginning of a program. It consists of the BEGIN keyword at the top-level of a program, followed by statements delimited by curly braces, and defines its own variable scope. If multiple BEGIN blocks are present, they are executed in the order encountered by the interpreter.
puts 1
BEGIN { puts 2 }
puts 3
# Output:
# 2
# 1
# 3
An END block, as opposed to the end keyword, is executed at the very end of a program. They consist of the END keyword followed by statements delimited by curly braces. Unlike BEGIN blocks, they share local variable scope with surrounding code. A further difference is that the execution of an END block is governed by surrounding constructs: if it appears in the body of a conditional, for instance, its execution is dependent on that conditional being true. However, even if enclosed in a looping construct, an END block is still only executed once.
puts 1
END { puts 2 }
puts 3
# Output:
# 1
# 3
# 2
An alternative to END blocks is Kernel.at_exit. It accepts a block argument which it registers to execute at the end of program execution. If called multiple times the blocks are executed in reverse chronological order.
at_exit { puts 1 }
puts 2
at_exit { puts 3 }
at_exit { puts 4 } if false
# Output:
# 2
# 3
# 1
An example, from Thor:
# Everytime someone inherits from a Thor class, register the klass
# and file into baseclass.
def inherited(klass)
Thor::Base.register_klass_file(klass)
klass.instance_variable_set(:@no_tasks, false)
end
# Fire this callback whenever a method is added. Added methods are
# tracked as tasks by invoking the create_task method.
def method_added(meth)
meth = meth.to_s
if meth == "initialize"
initialize_added
return
end
# Return if it's not a public instance method
return unless public_instance_methods.include?(meth) ||
public_instance_methods.include?(meth.to_sym)
return if @no_tasks || !create_task(meth)
is_thor_reserved_word?(meth, :task)
Thor::Base.register_klass_file(self)
end
You may want to make a script as an executable command. To do this with Wukong:
- include the ruby shebang (
#!
) line. -
require 'wukong/exe'
in your script. - define your Wukong jobflow, named the same as the script; the
.rb
suffix is optional.
Example: destroy_nukes.rb
#!/usr/bin/env ruby
require 'wukong/exe'
Wukong.job(:destroy_nukes) do
task(:reprogram, :description => "...")
end
Make the script executable:
chmod a+x destroy_nukes.rb
Now you can type:
destroy_nukes.rb ...
The wukong/exe
lib defines a ruby