What is this for?¶ ↑
This gem tries to solve a very specific problem when working with evented I/O code. Ideally, I suppose it would work with something like EventMachine, but I havent worked enough with EventMachine to know if that’s the case. Its meant for cases where blocks are passed to methods solely to sequence a set of steps. Like in this example.
writeFile(path, "hello") do File.open(path, "a") do |file| write(file, "\nworld") do close(file) do read(path) do |data| puts data.last end end end end end
Traditionally blocks have been a lightweight strategy pattern. Not so with evented I/O. While each function takes a block, this is merely to sequence the rest of the program to execute after the function is executed. To understand the context a little better read this
Installation¶ ↑
gem install step_rewrite
After installing the gem, the quick and dirty way to use it is to include the StepRewrite module in your code.
include StepRewrite step do path = "fileio.txt" writeFile(path, "hello", &_) file = File.open(path, "a", &_) write(file, "\nworld", &_) close(file, &_) data = read(path, &_) puts data.last end
The block passed to step is rewritten so that everywhere you have a method that takes &_ as a parameter, the rest of the code is passed as a block to it. So step rewrites this code into the code above and THEN evaluates it.
Rewrite Rules¶ ↑
Any code of the form
foo(&_) bar baz
gets rewritten to
foo do bar baz end
return values from such functions are converted into arguments to the block
a = foo(&_) bar(a) baz
becomes
foo do |a| bar(a) baz end
This allows an infinite degree of nesting
foo(&_) bar(&_) baz(&_) qux
becomes
foo { bar { baz { qux } } }
existing blocks or lambda parameters are not touched.
Other execution methods¶ ↑
If the name step clashes with a method in your code, you can instead use the module method
StepRewrite.step do path = "fileio.txt" writeFile(path, "hello", &_) file = File.open(path, "a", &_) write(file, "\nworld", &_) close(file, &_) data = read(path, &_) puts data.last end
if _ is a variable you are already using, you can configure the special callback identifier for rewriting.
StepRewrite.step(:cb) do path = "fileio.txt" writeFile(path, "hello", &cb) file = File.open(path, "a", &cb) write(file, "\nworld", &cb) close(file, &cb) data = read(path, &cb) puts data.last end
Define Method¶ ↑
The problem with the above approach is that it does not cache the result of rewriting the code. If what you are writing is part of a long running server, the recommended style is to define a method instead.
require 'step_rewrite/module' class IO define_step_method :hello_world do path = "fileio.txt" writeFile(path, "hello", &_) file = File.open(path, "a", &_) write(file, "\nworld", &_) close(file, &_) data = read(path, &_) puts data.last end end IO.new.hello_world
How does this work?¶ ↑
This gem makes use of the ParseTree gem to extract the sexp out of any block and then rewrites it using various rules. This code is converted back into Ruby using Ruby2Ruby and then evaled into a context
Copyright¶ ↑
Copyright © 2010 Vishnu Iyengar. See LICENSE for details.