Every repository with this icon (
Every repository with this icon (
Run the following if you haven't already:
gem sources -a http://gems.github.com
Install the gem(s):
sudo gem install larrytheliquid-Cry
| name | age | message | |
|---|---|---|---|
| |
.gitignore | Wed May 07 16:14:18 -0700 2008 | [Larry Diehl] |
| |
MIT-LICENSE | Sun May 11 17:29:10 -0700 2008 | [Larry Diehl] |
| |
README.rdoc | Wed Jun 04 22:55:05 -0700 2008 | [Larry Diehl] |
| |
Rakefile | Wed Jun 04 16:43:19 -0700 2008 | [Larry Diehl] |
| |
cry.gemspec | Wed Jun 04 22:02:42 -0700 2008 | [Larry Diehl] |
| |
cry.rb | Wed Jun 04 17:22:55 -0700 2008 | [Larry Diehl] |
| |
lib/ | Wed Jun 04 16:43:19 -0700 2008 | [Larry Diehl] |
| |
spec/ | Wed Jun 04 17:22:55 -0700 2008 | [Larry Diehl] |
Cry
A CommonLisp CLOS-like parse tree library for Ruby… read (and write) it and weep.
For example, you could create a parse tree like so:
parse_tree = Cry::ParseTree.new(:+, 1, 3)
… then evaluate it:
parse_tree.evaluate # => 4
… You can also create and evaluate more complex parse trees:
Cry::ParseTree.new( :+, Cry::ParseTree.new( :+, 1, Cry::ParseTree.new(:*, 2, 2) ), Cry::ParseTree.new(:+, 1, 3) ).evaluate # => 9
Lineage
Cry::ParseTree just inherits from Array, so you can use all of Array’s convenient methods for manipulating your ParseTrees too.
Parameter order
The first parameter is the method as a String or Symbol, this never changes.
The second parameter is the object that the method will be called on. This can either be a normal object, or an unevaluated Cry::ParseTree for delayed recursive evaluation.
Any subsequent parameters can either be normal objects, or Cry::ParseTrees, and will be passed as arguments to the method call.
Usage
require 'cry'
Cry::ParseTree.new(:*, Cry::ParseTree.new(:+, 1, 3), 23).evaluate # => 92
This is similar to the following Lisp:
(* (+ 1 3) 23) # => 92
Take note that ParseTree’s second parameter is always your object (be it a class or not).
The method specified will be called on the object, similar to CLOS.
To distinguish Cry::ParseTree objects from Arrays when using inspect, they are denoted by parentheses:
Cry::ParseTree.new(:<<, [1], 2).inspect # => "(:<<, [1], 2)"
Realize that you have access to all of Ruby, so you can do crazy things like this:
Cry::ParseTree.new(:instance_variable_set, self, '@parse_tree', 'Cry::ParseTree.new(:*, Cry::ParseTree.new(:+, 1, 3), 23).evaluate').evaluate
Cry::ParseTree.new(:eval, Kernel, @parse_tree).evaluate # => 92
Manipulation
The nice thing is that the parse trees are lazily evaluated. This means you can change them around before evaluations.
parse_tree = Cry::ParseTree.new(:+, 1, 3) parse_tree.node_method # => :+ parse_tree.node_object # => 1 parse_tree.node_arguments # => [3] parse_tree.node_method = :* parse_tree.node_object = 2 parse_tree.node_arguments = [4] parse_tree.evaluate # => 8
Also note that evaluate is not a destructive method.
parse_tree.evaluate # => 8 parse_tree.node_object = 3 parse_tree.evaluate # => 12
Blocks
To use methods that accept a block, just use a Proc for your last argument:
Cry::ParseTree.new(:inject, [1, 2, 3], 0, lambda{|sum, i| sum + i }).evaluate # => 6




