Posted by Jeremy Voorhis
Thu, 05 Jul 2007 22:10:00 GMT
And while I am becoming quite the language lawyer, I should mention that Ruby’s alias statement treats global variables quite differently from other kinds of variables.
When aliasing global symbols, the global variable itself is aliased and not evaluated. The result is a true alias, not a copy, so you cannot modify the global and its alias independently.
This feature most likely exists solely for English.rb in the standard library. This being the case, see that file for examples.
no comments
Posted by Jeremy Voorhis
Tue, 12 Jun 2007 22:13:00 GMT
I found the following snippet while reading the source for
Tempfile#initialize in the Ruby core library:
begin
tmpname = File.join(tmpdir, make_tmpname(basename, n))
lock = tmpname + '.lock'
n += 1
end while @@cleanlist.include?(tmpname) or
File.exist?(lock) or File.exist?(tmpname)
At first glance, I assumed the
while modifier would be evaluated before the contents of
begin...end, but that is not the case. Observe:
>> begin
?> puts "do {} while ()"
>> end while false
do {} while ()
=> nil
As you would expect, the loop will continue to execute while the modifier is true.
>> n = 3
=> 3
>> begin
?> puts n
>> n -= 1
>> end while n > 0
3
2
1
=> nil
While I would be happy to never see this idiom again,
begin...end is quite powerful. The following is a common idiom to memoize a one-liner method with no params:
def expensive
@expensive ||= 2 + 2
end
Here is an ugly, but quick way to memoize something more complex:
def expensive
@expensive ||=
begin
n = 99
buf = ""
begin
buf << "#{n} bottles of beer on the wall\n"
# ...
n -= 1
end while n > 0
buf << "no more bottles of beer"
end
end
2 comments
Posted by Jeremy Voorhis
Tue, 29 May 2007 23:56:00 GMT
Some weeks ago, after discovering Rack, I took it upon myself to experiment with my own anti-framework in Ruby, using existing libraries whenever possible and filling in the blanks as I go. A vital piece of most web frameworks is the dispatcher – the module that delegates web requests to application code.
The basic premise of my design is to encode common data structures within the path of a url, and to lookup the appropriate action in a dispatch table. I don’t have a working dispatcher yet, but I do have this:
irb(main):002:0> UrlParser.parse("/foo/1,2,3/meep=fleem;fliffl=mumble,grumble/")
=> [["foo"], ["1", "2", "3"], {"meep"=>["fleem"], "fliffl"=>["mumble", "grumble"]}]
The simple language uses a slash to separate values, a comma to group them into a list, and equals and semi-colon together to create a hash. The values are returned as a list.
The next step is to determine the semantics of how an action is selected. My tastes would be satisfied by a very simple form of pattern matching, with this approximate syntax, mixing literals and types:
register(:module => PostsController, :action => :show,
:path => ['posts', Integer], :method => GET)
Further refinements to the path language might include recognizing ints and floats, and distinguishing between array and scalar values.
If you find the idea interesting, or even terrible, I’d love to hear your thoughts on both the path language and the dispatching semantics.
p.s. No, I’m not actually calling this “Urlang”.
no comments
Posted by Jeremy Voorhis
Fri, 18 May 2007 16:34:39 GMT

1 comment
Posted by Jeremy Voorhis
Thu, 03 May 2007 22:59:00 GMT
While prototyping a RESTful web service, I wrote the following code to allow Rails to parse a request’s parameters from a POST request containing JSON.
ActionController::Base.param_parsers[Mime::JSON] = JSON.method(:parse)
Unfortunately, it did not work, while the following code did:
ActionController::Base.param_parsers[Mime::JSON] = lambda { |data| JSON.parse(data) }
Theoretically, both of these should accomplish the same thing: assign an object that responds to the message call with an arity of 1 to Mime::JSON entry of the param_parsers hash. They lead to different results, however, because a case statement within the Rails HTTP request parsing code watches for an instance of Proc, instead of an object which responds to call.
As a proof of concept, I whipped up this DuckType class:
class DuckType
def initialize(*args)
@args = args
end
def ===(other)
@args.all? { |arg| other.respond_to?(arg) }
end
end
Now, we can replace this statement from
cgi_methods.rb
case strategy = ActionController::Base.param_parsers[mime_type]
when Proc
strategy.call(raw_post_data)
# snip...
end
with the following:
Callable = DuckType.new :call
case strategy = ActionController::Base.param_parsers[mime_type]
when Callable
strategy.call(raw_post_data)
# snip...
end
As you can see, an instance of DuckType has a case comparison operator which asserts that all specified messages are supported, allowing you to focus on an object’s capabilities rather than its class.
My DuckType implementation in its current form is rather crude, but if enough people found this technique useful, I would consider properly packaging and extending it for general use.
9 comments
Posted by Jeremy Voorhis
Tue, 10 Apr 2007 15:52:00 GMT
After re-reading Nat Pryce’s Scrapheap Challege writeup, I tried to see how easily I could answer a simple question with only lynx, grep and friends. It turns out to be even simpler than I suspected. For example, the following tells me that my average blog post receives 2.2 comments.
# iterate through 17 pages
page=1; until [ $page -eq 17 ] ; do
lynx -dump "http://www.jvoorhis.com/articles/page/$page" | \
egrep "([[:digit:]]+|no) comments?" | \
sed -e "s/\[.*\]//g" -e "s/no/0/g" | \
awk '{print $1}' >> comments.txt
page=$(( page + 1 ))
done
avg comments.txt
12 comments
Posted by Jeremy Voorhis
Sun, 08 Apr 2007 22:16:00 GMT
Two days ago, I discovered Module#method_added lurking about in the DRP library. Today, let’s take a look at what it does, along with an example implementation of multiple dispatch for Ruby objects.
Module#method_added accepts one parameter – a symbol allowing us to reference the method that was just defined in a class or module definition. We may do a number of things with only that method name – inspect the method, rename it, change its scope, or – in our case – register it with our multiple dispatch system.
The following code is both crude and simple: it allows us to define multimethods based on their arity, and does not support optional arguments or variable-length argument lists. It also only takes hold within the multi do ... end block. With a little extra work, the multi block could be eliminated, and missing features could be added. What is noteworthy is how reflective callbacks such as Module#method_added and Class#inherited make it possible to use the Ruby language to extend the Ruby language.
module Multi
module Arity
def method_added(name)
if @__multi_def__
@__multi_def__ = false # Disable method_added behavior while aliasing
arity = instance_method(name).arity
@__multi_methods__ |= [name]
class_eval "private :#{name}; alias __multi__#{name}__#{arity} #{name}"
@__multi_def__ = true
end
end
def multi
@__multi_methods__ = []
@__multi_def__ = true
yield
@__multi_def__ = false
@__multi_methods__.each do |name|
define_method(name) { |*args| send("__multi__#{name}__#{args.size}", *args) }
end
end
end
end
if __FILE__ == $0
require 'test/unit'
class Example
extend Multi::Arity
multi do
def hello
"Hello, somebody"
end
def hello(name)
"Hello, #{name}"
end
end
end
class MultiTest < Test::Unit::TestCase
def test_dispatch
ex = Example.new
assert_equal "Hello, somebody", ex.hello()
assert_equal "Hello, multimethods", ex.hello("multimethods")
end
end
end
4 comments
Posted by Jeremy Voorhis
Fri, 06 Apr 2007 20:47:00 GMT
Inspired by the eigenclass language generator, I’ve thrown together an example of how it would be implemented with the Directed Ruby Programming library. Directed programming is an interesting hybrid of genetic programming and the recently discovered grammatical evolution technique which generates a program tree according to a grammar.
This example may not be very interesting for those familiar with evolutionary programming techniques, but it created a fun diversion, highlights how the DRP library is to be used, and shows a different solution for a language generator.
class DrpGenerator
extend DRP::RuleEngine
begin_rules
def main() "#{hello}\n#{ex1}\n#{ex2}" end
def hello() "Hello, #{somebody}!" end
def somebody() "matz" end
def somebody() "world" end
def ex1() "This is a more #{adj1} #{example}." end
def adj1() "complex" end
def adj1() "elaborate" end
def example() "example" end
def example() "test" end
def ex2() "Some simple sentence." end
def ex2() "Another, involving harder stuff." end
def ex2() "Another, involving a more complex #{exp}." end
def ex2() "Yet another possibility; each one is chosen with an evolutionary algorithm." end
def exp() "expression" end
def exp() "disjunction" end
def exp() example end
end_rules
end
g = DrpGenerator.new
3.times { puts g.main }
Hello, matz!
This is a more elaborate example.
Another, involving a more complex disjunction.
Hello, world!
This is a more elaborate test.
Another, involving harder stuff.
Hello, world!
This is a more complex example.
Yet another possibility; each one is chosen with an evolutionary algorithm.
My DrpGenerator isn’t as readable or attractive as the eigenclass DSL, and multiple definitions of the same method will likely confuse most Rubyists at first glance, but makes it easy to see the underlying grammar.
3 comments