diff --git a/Changes b/Changes index e2fc4a349a..e56770a013 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,7 @@ -5.16 2014-07-19 +5.16 2014-07-20 + - Added empty method to Mojo::Cache. + - Added flush method to Mojolicious::Routes. 5.15 2014-07-17 - Improved Mojo::DOM::HTML performance slightly. diff --git a/lib/Mojo/Cache.pm b/lib/Mojo/Cache.pm index 681d4d79a4..0462a2a7a1 100644 --- a/lib/Mojo/Cache.pm +++ b/lib/Mojo/Cache.pm @@ -3,6 +3,8 @@ use Mojo::Base -base; has 'max_keys' => 100; +sub empty { delete shift->{cache} } + sub get { (shift->{cache} || {})->{shift()} } sub set { @@ -10,7 +12,7 @@ sub set { my $cache = $self->{cache} ||= {}; my $queue = $self->{queue} ||= []; - delete $cache->{shift @$queue} if @$queue >= $self->max_keys; + delete $cache->{shift @$queue} while @$queue >= $self->max_keys; push @$queue, $key unless exists $cache->{$key}; $cache->{$key} = $value; @@ -53,6 +55,12 @@ Maximum number of cache keys, defaults to C<100>. L inherits all methods from L and implements the following new ones. +=head2 empty + + $cache->empty; + +Empty cache. + =head2 get my $value = $cache->get('foo'); diff --git a/lib/Mojo/UserAgent/CookieJar.pm b/lib/Mojo/UserAgent/CookieJar.pm index c2d57aefd1..ba89dc3ae8 100644 --- a/lib/Mojo/UserAgent/CookieJar.pm +++ b/lib/Mojo/UserAgent/CookieJar.pm @@ -36,7 +36,7 @@ sub all { return map { @{$jar->{$_}} } sort keys %$jar; } -sub empty { shift->{jar} = {} } +sub empty { delete shift->{jar} } sub extract { my ($self, $tx) = @_; diff --git a/lib/Mojolicious/Guides/Routing.pod b/lib/Mojolicious/Guides/Routing.pod index ac99d1a2ef..2e061cc8ba 100644 --- a/lib/Mojolicious/Guides/Routing.pod +++ b/lib/Mojolicious/Guides/Routing.pod @@ -804,10 +804,10 @@ unescaped and decoded from bytes to characters. =head2 Rearranging routes -Until the first request has been handled, all routes can still be moved around -or even removed with methods like L -and L. Especially for rearranging routes -created by plugins this can be very useful. +All routes can be moved around or even removed with methods like +L and +L, after the first request has been +handled this can affect performance though. # GET /example/show -> {controller => 'example', action => 'show'} my $show = $r->get('/show')->to('example#show'); @@ -817,7 +817,8 @@ created by plugins this can be very useful. $r->get('/secrets/show')->to('secrets#show')->name('show_secrets'); $r->find('show_secrets')->remove; -To find routes by their name you can use L. +Especially for rearranging routes created by plugins this can be very useful, +L is used to locate routes by their name. =head2 Conditions diff --git a/lib/Mojolicious/Routes.pm b/lib/Mojolicious/Routes.pm index 82fd6ba01b..1b278c3e45 100644 --- a/lib/Mojolicious/Routes.pm +++ b/lib/Mojolicious/Routes.pm @@ -53,6 +53,12 @@ sub dispatch { return 1; } +sub flush { + my $self = shift; + if (my $cache = $self->cache) { $cache->empty } + delete $self->{reverse}; +} + sub hide { push @{shift->hidden}, @_ } sub is_hidden { @@ -334,6 +340,12 @@ every action. Match routes with L and dispatch with L. +=head2 flush + + $r->flush; + +Flush caches and allow routes to be changed again. + =head2 hide $r = $r->hide(qw(foo bar)); diff --git a/lib/Mojolicious/Routes/Route.pm b/lib/Mojolicious/Routes/Route.pm index 233137bdcc..599e436e5c 100644 --- a/lib/Mojolicious/Routes/Route.pm +++ b/lib/Mojolicious/Routes/Route.pm @@ -115,6 +115,7 @@ sub put { shift->_generate_route(PUT => @_) } sub remove { my $self = shift; return $self unless my $parent = $self->parent; + $self->root->flush; @{$parent->children} = grep { $_ ne $self } @{$parent->children}; return $self->parent(undef); } diff --git a/t/mojo/cache.t b/t/mojo/cache.t index 03442dc63a..19217108c2 100644 --- a/t/mojo/cache.t +++ b/t/mojo/cache.t @@ -19,6 +19,13 @@ is $cache->get('foo'), undef, 'no result'; is $cache->get('bar'), undef, 'no result'; is $cache->get('baz'), 'yada', 'right result'; is $cache->get('yada'), 23, 'right result'; +$cache->empty; +is $cache->get('baz'), undef, 'no result'; +is $cache->get('yada'), undef, 'no result'; +$cache->max_keys(1)->set(one => 1)->set(two => 2)->set(three => 3); +is $cache->get('one'), undef, 'no result'; +is $cache->get('two'), undef, 'no result'; +is $cache->get('three'), 3, 'right result'; $cache = Mojo::Cache->new(max_keys => 3); is $cache->get('foo'), undef, 'no result'; diff --git a/t/mojolicious/app.t b/t/mojolicious/app.t index bd54c58513..fc40db1bc2 100644 --- a/t/mojolicious/app.t +++ b/t/mojolicious/app.t @@ -269,6 +269,14 @@ $t->get_ok('/happy/fun/time' => {'X-Test' => 'Hi there!'})->status_is(200) ->header_is('X-Bender' => undef)->header_is(Server => 'Mojolicious (Perl)') ->content_is('Have fun!'); +# Foo::index (modify routes at runtime) +ok $t->app->routes->cache, 'routes are cached'; +$t->get_ok('/foo/index')->content_like(qr/Hello Mojo/); +$t->app->routes->get('/foo/index' => {text => 'new route'}); +$t->app->routes->add_child($t->app->routes->find('default')); +$t->get_ok('/foo/index')->content_is('new route'); +ok $t->app->routes->cache, 'routes are still cached'; + # Foo::test $t->get_ok('/foo/test' => {'X-Test' => 'Hi there!'})->status_is(200) ->header_is('X-Bender' => 'Bite my shiny metal ass!') diff --git a/t/mojolicious/lib/MojoliciousTest.pm b/t/mojolicious/lib/MojoliciousTest.pm index dbff2186af..84bd3f9aaa 100644 --- a/t/mojolicious/lib/MojoliciousTest.pm +++ b/t/mojolicious/lib/MojoliciousTest.pm @@ -156,7 +156,7 @@ sub startup { $r->route('/rss.xml')->to('foo#bar', format => 'rss'); # /*/* (the default route) - $r->route('/(controller)/(action)')->to(action => 'index'); + $r->route('/(controller)/(action)')->to(action => 'index')->name('default'); # /just/some/template (embedded template) $r->route('/just/some/template')->to(template => 'just/some/template'); diff --git a/t/mojolicious/routes.t b/t/mojolicious/routes.t index 6c91d0524b..511ee5599d 100644 --- a/t/mojolicious/routes.t +++ b/t/mojolicious/routes.t @@ -181,7 +181,9 @@ my $third = $source->route('/third')->to('#third'); my $target = $r->remove->route('/target')->to('target#'); my $second = $r->find('second'); is $second->render('', {}), '/source/second', 'right result'; +is $r->cache(0)->lookup('second'), $second, 'route does exist'; $second->remove; +isnt $r->lookup('second'), $second, 'route does not exist'; is $second->render('', {}), '/second', 'right result'; $target->add_child($first)->add_child($second); is $second->render('', {}), '/target/second', 'right result';