Chapter 7. Slices

As we add more features to a Merb application, we may find that some are generic enough to be applicable to other apps. Whereas in the past you may have copied and pasted the relevant controller, views, and models from one application to another, Merb slices allow you to genuinely refactor the code encapsulating them within a gem. This gem can then be included with multiple applications, allowing for application-level overriding of particulars, for instance. In this chapter we’ll go through both the anatomy of slices as well as the source that makes them possible.

7.1 Slice development

Slice development practices have been designed to mimic those of standard applications. There are some differences, though, that you need to be aware of. In this section we’ll shed some light on the basics of generating, running, and using a slice.

7.1.1 Generating slices

The generation of a slice is similar to the generation of a Merb application. Using merb-gen, we can create the skeleton for our slice:

image

You’ll notice that some of these files are particular to slices, most importantly the files in lib and in stub. Let’s open up the most important of them, lib/merb-forums-slice.rb:

image

image

The first thing to note is that the code adds the lib directory to the list of locations from which required files can be found. This makes the slice’s local dependencies easy to find even from the host application. The code then proceeds to add various rake task files that may be used for slice maintenance. If your slice needs custom rake tasks, inside one of these files is the best place to put them. The next thing done is the registration of the slice. Note that the register method uses the full fill path to do this. If we peek into the method itself, located in the merb-slices source, we can understand why:

image

The snippet of source above reveals that register prefers the filename so that we can register multiple cascading slices of the same name. The two most important things to take away from this are that slice module names are inferred from the included file’s filename and that a second parameter allows us to turn off the cascading nature of slices by passing in false.

Going back to lib/merb-forums-slice.rb, we come across the module MerbForumsSlice and can recognize its importance in being named such. At the start of this module is some metadata that could be used by the master application to identify what slices and slice versions it is using. Below this we find empty hook methods that will allow us to enhance the activation and deactivation of the module. The final and possibly most interesting section of the module is the router block. Though a config/router.rb exists for standardly generated Merb slices, it is intended only for testing isolated slices and not employed by slices that are activated through full apps. Instead, the method setup_router is used to scope slices relative to slice paths. This is critically important for the slice developer to remember: Router configuration happens in the slice file and requires the use of scope. Otherwise, routes are defined exactly the same.

7.1.2 Running slices

Having generated a slice, we can fire it up as if it were an isolated application. We can use the command slice from within the slice’s top directory in the same way we would use merb:

image

As you can see, we were even able to use the console trap option -C and then pull up an IRB console for our slice. Additionally, if we visit localhost:4000, we’ll be presented with a simple page showing off the metadata from our slice.

You may be interested in knowing how the slice command works and how it is different from the standard merb command. Opening up the executable file itself, we can differentiate the two:

image

image

image

image

We moved a line or two around, but otherwise you’ll find that slice is identical to merb, excluding the long section in the middle. This region of code handles, among many other things, finding and requiring the lib files, the creation of a default route, and the explicit setting up of a simple controller to display metadata if no other default action exists. One subtlety to notice, which may trip you up otherwise, is that in finding the appropriately named lib/ slice file, slice uses the present working directory name. In other words, the name of the directory containing the slice does in fact matter and should match the name of the lib/ slice file.

7.1.3 Building slices

Building a slice into a gem is an incredibly easy part of the slice development process. All there is to be done is editing the Rakefile to set the appropriate gem specifications and then running the rake task install. This builds and installs a gem containing your slice. This gem can also be found in pkg/ and distributed to others directly or put up on a Ruby gem server. When required as a Merb dependency, the gem includes the slice application code as part of the full Merb application. Let’s take a look at the relevant sections of the Rakefile that make this work:

image

As a slice developer, you may need to venture only as far as the constant lines to get your work done. However, we’ve also included the code for the install rake task to show off the usage of a Merb rake helper. Venturing into the source code of the Merb::RakeHelper is left as an exercise for the reader.

7.1.4 Slice controllers

A number of methods are mixed into the AbstractController class and meant for use within Merb controller slices. For the most part these methods can be tucked away, leaving application code within a Merb slice indistinguishable. As an example, let’s open up the default-generated application controller within a slice:

image

This lone class method does three things. First, it determines the slice module in which the class is resting, checks if it should be active, and if so stores a reference to the containing module under the class-inheritable reader slice. Second, it sets up proper template root directories for all inheriting slice controllers. Finally, it uses the method layout_for_slice to enhance the selection of the default layout so that we can specify a host-overriding slice layout for our templates. The easiest way to do so is to pass in a hash containing a key-and-value pair for :layout as a parameter to controller_for_slice.

7.2 Slice usage

A number of methods are added to the router when the merb-slices gem is required. These methods are meant to bridge individual slices with the host application by allowing us to specify which routes should be handled by which slices. However, only one of these router extension methods is intended to be used by the application developer: slice. Below we have used it to add the forums slice to our host application.

image

The most useful option that we can use with slice is path. It effectively prepends the route path to all slice routes. Below we push forums into the path /community.

image

Here’s the code for the slice extension method:

image

The method merges in the option to reset the controller prefix. This is necessary because without it a controller prefix is used on the routes. Aside from that, slice basically delegates to add_slice, another router extension method that we advise application developers to stay away from unless they intend to use a controller prefix. For the sake of clarity on other options, here’s the source to add_slice:

image

image

From the perspective of a student of the frameworks, the most interesting code above is in the lines where the route namespace is created. Particularly be aware of the use of the behavior method capture, which simply collects a hash of routes as they are added within its block without affecting the routes themselves in any way. This method, which you may have written off, actually allows Merb to store a partitioned list of routes related to particular slices, a necessity for the dynamic deactivation of slices.

7.3 Conclusion

Merb slices are one of the most attractive features from an application developer’s perspective because they increase the ease and reusability of code. The second version of Merb was intended to make great strides toward dynamic activation of Merb slices and build an arsenal of slices for developers to share. However, given the merge, such work has been put on hold until a similar system is settled upon within Rails 3.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.176.194