I was browsing the camping
documentation, and I ran into this example for defining a controller:
class Digits < R '/nuts/(\d+)'
def get(number)
"You got here by: /nuts/#{number}"
end
end
It looks like what this class definition is doing is that it's passing a string argument to the R
superclass. However, I looked through the camping
codebase and I didn't see R
defined as a class anymore. It was defined as a method like this:
def R(c,*g)
p,h=/\(.+?\)/,g.grep(Hash)
g-=h
raise "bad route" if !u = c.urls.find{|x|
break x if x.scan(p).size == g.size &&
/^#{x}\/?$/ =~ (x=g.inject(x){|x,a|
x.sub p,U.escape((a.to_param rescue a))}.gsub(/\\(.)/){$1})
}
h.any?? u+"?"+U.build_query(h[0]) : u
end
and the method to actually handle the route:
def /(p); p[0] == ?/ ? @root + p : p end
I don't understand exactly how this works, because when I tried to make a class and define a method as a superclass, like this:
def doSomething(boo)
puts boo
end
class Someclass < doSomething 'boo'
end
I get this error:
(eval):60: (eval):60: superclass must be a Class (NilClass given) (TypeError)
Can someone point me to where in the ruby documentation this feature (using a method as a superclass) is covered? I don't know what to call this feature, so my googling efforts couldn't really find me anything.
You'll have to return a class from your method:
def doSomething(boo)
Class.new { define_method(:boo) { boo } }
end
class SomeClass < doSomething 'boo'
end
SomeClass.new.boo # => 'boo'
You're also looking at the wrong method. Camping has a class method on Controllers called R
(that's the one used when defining controllers) and an instance method on Base called R
(for generating routes). This is the actual definition: https://github.com/camping/camping/blob/ae5a9fabfbd02ba2361ad8831c15d723d3740b7e/lib/camping-unabridged.rb#L551