GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Rubygem
Description: Resource-oriented open source Ruby framework for Web apps.
Homepage: http://rubywaves.com/
Clone URL: git://github.com/dyoder/waves.git
"Buggy" is a relative term. The new mapping code is, however, pretty much 
code-complete.
dyoder (author)
Sun Jun 22 17:56:40 -0700 2008
commit  c20eee436e590e06afd629fb3caddeebed55dfb8
tree    cadf6925aa471b3a859a7e81027616d41347f0e0
parent  435b06a0e80708dbe252b0e2c02ebc548357687b
...
41
42
43
44
 
45
46
47
48
49
...
41
42
43
 
44
45
 
46
47
48
0
@@ -41,9 +41,8 @@ module Waves
0
           
0
           begin
0
             response.write( mapping[ :action ].first.call( request ) )
0
- rescue Exception => e
0
+ ensure
0
             mapping[ :after ].each { | action | action.call( request ) }
0
- raise e
0
           end
0
           
0
         rescue Exception => e
...
63
64
65
66
67
 
 
68
69
 
70
71
72
...
63
64
65
 
 
66
67
68
 
69
70
71
72
0
@@ -63,10 +63,10 @@ module Waves
0
 
0
           auto_eval :Resources do
0
             const_set( :Default, Class.new( Waves::Resources::Base ) ).module_eval do
0
- def controller ; @controller ||= controllers[ resource ].process( @request ) { self } ; end
0
- def view ; @view ||= views[ resource ].process( @request ) { self } ; end
0
+ def controller ; @controller ||= controllers[ singular ].process( @request ) { self } ; end
0
+ def view ; @view ||= views[ singular ].process( @request ) { self } ; end
0
               def action( method, *args ) ; @data = controller.send( method, *args ) ; end
0
- def render( method ) ; view.send( method, ( @data.kind_of?( Enumerable ) ? resources : resource ) => @data ) ; end
0
+ def render( method ) ; view.send( method, ( @data.kind_of?( Enumerable ) ? plural : singular ) => @data ) ; end
0
               def method_missing( name, *args, &block) ; params[ name.to_s ] ; end
0
             end
0
             auto_create_class true, self::Default
...
18
19
20
21
 
22
23
24
...
18
19
20
 
21
22
23
24
0
@@ -18,7 +18,7 @@ module Waves
0
           @resource = Waves::Resources::Proxy
0
         end
0
         resource.instance_eval { define_method name, &block } if name and block_given?
0
- resource.paths.instance_eval { meta_def name, &pattern.generator }
0
+ resource::Paths.instance_eval { define_method( name ) { |*args| generate( options[ :pattern ], args ) } }
0
       end
0
       
0
       def bind( request )
...
8
9
10
11
12
13
14
15
 
 
16
17
18
19
20
 
 
 
 
 
 
 
21
22
23
24
25
26
27
 
 
 
 
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
 
 
 
 
 
 
 
47
48
49
...
8
9
10
 
 
11
 
 
12
13
14
15
 
 
 
16
17
18
19
20
21
22
23
 
 
 
 
 
 
24
25
26
27
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
30
31
32
33
34
35
36
37
38
39
0
@@ -8,42 +8,32 @@ module Waves
0
       
0
       include Functor::Method
0
       
0
- attr_accessor :target, :pattern, :generator
0
-
0
       def initialize( options )
0
- @keys = [] ; @target = options[ :target ]
0
- compile( options[ :pattern ] )
0
+ @target = options[ :target ]
0
+ @pattern = options[ :pattern ]
0
       end
0
       
0
- def match( request )
0
- return false unless m = @pattern.match( request.send( target ) )
0
- zip( @keys, m[1..-1] )
0
+ functor( :match, Waves::Request ) { | request | match( @pattern, request.send( @target ) ) }
0
+ functor( :match, Array, String ) { | pattern, path | match( pattern, path.split('/')[1..-1] ) }
0
+ functor( :match, Array, Array ) do | wants, gots |
0
+ r = {}; matches = wants.all? do | want |
0
+ match( r, want, gots.shift )
0
+ end
0
+ r if matches and gots.empty?
0
       end
0
-
0
- private
0
-
0
- functor( :compile, Array ) do | path |
0
- @generator = lambda { |*args| self.instance_eval { generate( path, args ) } }
0
- @pattern = Regexp.new( '^/' + path.map { |component| compile( component ) }.join('/') + '/?$' )
0
+ functor( :match, Hash, String, String ) { | r, want, got | got if want == got }
0
+ functor( :match, Hash, Regexp, String ) { | r, want, got | got if want === got }
0
+ functor( :match, Hash, Symbol, String ) do | r, want, got |
0
+ r[ want.to_s ] = got if match( r, /([\w\_\-\#]+)/, got )
0
       end
0
-
0
- functor( :compile, String ) { |s| Regexp.escape( s ) }
0
- functor( :compile, Regexp ) { |re| s }
0
- functor( :compile, Symbol ) { |sy| @keys << sy.to_s ; '([\w\_\-\#]+)' }
0
- functor( :compile, Hash ) { |h| @keys << h; '([\w\_\-\#]+)?' }
0
-
0
- # this is a bit different than Array#zip ...
0
- functor( :zip, Array, Array ) { | keys, vals | keys.inject( {} ) { | h, key | n, m = zip( key, vals ) ; h[ n ] = m ; h } }
0
- functor( :zip, String, Array ) { | key, vals | [ key, vals.shift ] }
0
- functor( :zip, Hash, Array ) { | h, vals | key = h.keys.first ; [ key.to_s, ( vals.shift || h[ key ] ) ] }
0
-
0
- functor( :generate, Array, Array ) { | keys, vals | keys.map { |key| generate( key, vals ) }.compact.join('/') }
0
- functor( :generate, :resource, Array ) { | key, vals | resource }
0
- functor( :generate, :resources, Array ) { | key, vals | resources }
0
- functor( :generate, Symbol, Array ) { | key, vals | generate( key, vals.shift ) }
0
- functor( :generate, Symbol, Symbol ) { | key, val | val }
0
- functor( :generate, Regexp, Array ) { | key, vals | nil }
0
- functor( :generate, Hash, Array ) { | h, vals | vals.shift || h.values.first }
0
+ functor( :match, Hash, Hash, String ) do | r, want, got |
0
+ key = want.keys.first
0
+ r[ key.to_s ] = match( r, key, got )
0
+ end
0
+ # hashes represent optional values with a default
0
+ functor( :match, Hash, Hash, nil ) { | r, want, got | r[ want.keys.first.to_s ] = want.values.first }
0
+ # everything else is mandatory ...
0
+ functor( :match, Hash, Object, nil ) { | r, want, got | false }
0
       
0
     end
0
 
...
9
10
11
12
 
 
 
 
 
 
 
 
13
14
15
16
17
 
 
18
19
20
...
9
10
11
 
12
13
14
15
16
17
18
19
20
21
22
 
 
23
24
25
26
27
0
@@ -9,12 +9,19 @@ module Waves
0
       include ResponseMixin
0
       
0
       def self.included( target )
0
- def target.paths ; @paths ||= Object.new ; end
0
+ parent = target.superclass
0
+ base = parent.respond_to?( :paths ) ? parent.paths : Waves::Mapping::Paths
0
+ target.module_eval do
0
+ const_set( :Paths, Class.new( base ) )
0
+ def self.paths ; @object ||= self::Paths.new( self ) ; end
0
+ def self.singular ; basename.downcase ; end
0
+ def self.plural ; basename.downcase.plural ; end
0
+ end
0
       end
0
       
0
       def initialize(request); @request = request ; end
0
- def resource ; self.class.basename.downcase ; end
0
- def resources ; resource.plural ; end
0
+ def singular ; self.class.singular ; end
0
+ def plural ; self.class.plural ; end
0
       def redirect( path ) ; request.redirect( path ) ; end
0
       def paths ; self.class.paths ; end
0
       
...
57
58
59
 
60
61
62
...
57
58
59
60
61
62
63
0
@@ -57,6 +57,7 @@ require 'mapping/action'
0
 require 'mapping/pattern'
0
 require 'mapping/constraints'
0
 require 'mapping/descriptors'
0
+require 'mapping/paths'
0
 require 'resources/mixin'
0
 require 'resources/proxy'
0
 
...
8
9
10
11
 
12
13
14
15
16
 
17
18
 
19
20
21
...
8
9
10
 
11
12
13
14
15
 
16
17
 
18
19
20
21
0
@@ -8,14 +8,14 @@ module Blog
0
       
0
       # specific to comments - on create redirect to the entry, not the comment itself
0
       path :create, :resource => :comment, :post => [ '/comments' ] do
0
- redirect( Blog::Resources::Entries.paths.show( action( :create ).entry.name ) )
0
+ redirect( Blog::Resources::Entries.paths.read( action( :create ).entry.name ) )
0
       end
0
       
0
       # defaults for generic resources
0
       path( :list, :get => [ :resources ] ) { action( :all ) and render( :list ) }
0
- path( :create, :post => [ :resources ] ) { redirect( paths.edit( action( :create ).name ) ) }
0
+ path( :create, :post => [ :resources ] ) { redirect( paths.read( action( :create ).name, 'edit' ) ) }
0
       path( :read, :get => [ :resource, :name, { :mode => 'show' } ] ) { action( :find, name ) and render( mode ) }
0
- path( :update, :put => [ :resource, :name ] ) { action( :update, name ) and redirect( paths.show( name ) ) }
0
+ path( :update, :put => [ :resource, :name ] ) { puts "REDIRECT: #{paths.read( name ) }" ; action( :update, name ) and redirect( paths.read( name ) ) }
0
       path( :delete, :delete => [ :resource, :name ] ) { action( :delete, name ) }
0
       
0
     end
...
1
2
3
 
4
5
6
...
1
2
 
3
4
5
6
0
@@ -1,6 +1,6 @@
0
 layout :default, :title => @entry.title do
0
   a 'Show All Entries', :href => '/entries'
0
- a 'Edit This Entry', :href => "/entry/#{@entry.name}/editor"
0
+ a 'Edit This Entry', :href => "/entry/#{@entry.name}/edit"
0
   h1 @entry.title
0
   textile @entry.content
0
   h1 'Comments'

Comments

    No one has commented yet.