Save Time and Effort with Facets

by Christian Romney

Given the immense popularity of Rails, it's easy to overlook some of the other goldmines of the Ruby world. One of these gems is the Facets library. A collection of general-purpose methods and modules, Facets can keep you from engaging in repeated wheel-reinvention exercises in your Ruby projects. Most burgeoning Rubyists know to explore the Ruby Standard library, but I am continually surprised when talking with new Ruby developers who've never heard of Facets.


17 Comments

evan
2006-12-13 21:16:53
Can you mention what other facets you think are the most useful? Facets scope is humongous, but its organization is rather poor, which has turned me off until now.
Christian Romney
2006-12-14 04:41:32
Evan,


I generally pick out single facets that help me solve a problem, and sometimes that does mean going spelunking through the class list. The likely targets are usually Array, Hash, String, and Enumerable. Another favorite of mine, however, is *alias_method_chain* which encapsulates a common pattern for adding new functionality (or a new branch point) to an existing method. I've used alias_method_chain to add a new type of filter to Rails controllers - before_render - which lets you run methods after the controller action's code, but before control is handed over to the view.

Chris
2006-12-14 09:12:11
Did those "rockstars" actually contribute to Facets, or had they blogged cool code that the Facets guys then incorporated into their project?
Christian Romney
2006-12-14 10:21:30
Chris,


Well the Facets page explicitly thanks them and others who are far too numerous to mention here. But I have to ask, does it really matter? Assuming for a moment that they didn't contribute directly, by virtue of their code being open and good they've already done the community a service. The mechanics really don't matter to me that much. From the limited interaction I had with Jim, Jamis, and _why directly at RailsConf EU, however, I can say that they are all quite friendly and approachable and the mailing lists bear out their goodwill.

Greg
2006-12-15 10:51:09

So the next time you find yourself about to write code to return each combination of the elements of an Array, do yourself a favor and check out Facets instead.


The problem I see with facets is it's too disjoint. Usually any neat function I've seen in facets is cool on it's own, but I don't want to pull in an all in wonder tool chest if I don't have to. I know you can selectively choose what you'd like to use and what not, but I think the 'all eggs in one basket' approach of the project is a bit of a turn off.

Christian Romney
2006-12-15 10:59:11
Greg,


You can actually load just the particular methods you want. Say you only want Array#each_combination, you could require just that one file. The finely-grained control is one of the coolest parts about Facets.

Greg
2006-12-15 11:20:12
Christian,


See my post:


I know you can selectively choose what you'd like to use and what not


My feeling is that I do not want to make Facets a dependency just to select one method.

Christian Romney
2006-12-15 11:29:59
Greg,


Sorry I misunderstood you. I grant you that in some cases you may not want the dependency. I suppose a viable, though sub-optimal solution in these cases would be to simply lift the source code for the methods you want and place them within your project. I still think it beats rolling your own methods in those cases where there's a ready-made one waiting in the wings. I'll admit I usually have my say of what dependencies to require, and given the growth of virtualization and VPSs I think we'll see a lot more developers having free reign in the future. I'd love you thoughts on the topic. What kind of dependency issues do you encounter most frequently and how do you resolve them?

Greg
2006-12-15 11:49:43
Well, I'm not opposed to dependencies.


Rubygems makes dependency handling trivial for the most part.


My issue with something like Facets is that it changes the core in a broad and narrow way. If I make gratuitous use of these addons, it's going to confuse contributors when they see the stuff, and lacking the ability to dig into the source *right in my project*, I think it might lead them to get frustrated.


I think facets is too general of a project and offers a sort of 'grab bag of features' which will make it eternally difficult to organize.


I don't like the idea of relying on an external library for a super-duper-general method that I could roll on my own quickly enough, because it makes maintainence annoying.


Note that i'm mostly talking about using Facets inside of fairly general libraries... not things people are doing for specific projects.


Also, I think some of the things in there totally rock. It's a cool test bed for potential RCRs. I never thought of it as something to consider using seriously in production code, though.

Greg
2006-12-15 11:52:16
hehe, in my last comment, I meant to say "broad and shallow"


Not necessarily as a negative term, just as in 'we're going to make a whole bunch of little improvements'

Christian Romney
2006-12-15 12:03:32
Hmm, I guess my main considerations for dependencies are time saved and code quality. As you mentioned it's trivial to add dependencies to Rubygems and if I were going to right libraries I'd probably go that route to avoid the kind of confusion you pointed out. I also think that confusion is mitigated a bit if the consumers of your library have experience with Ruby and can quickly recognize which methods are not in the standard lib. I'll concede, however, that you *rarely* have the luxury of controlling that variable. :)


As for private projects, though, I say full steam ahead. A little documentation can also help keep the dependency beast under control. As with anything, it's a matter of weighing the trade-offs. And thanks for your comments, I appreciate the dialogue. Cheers!

Christian Romney
2006-12-15 12:04:57
Ugh, forgive my /right/write and many other literary failings. I need to spell check before I comment.
trans
2006-12-18 23:55:08
wow! took me by surprise. thanks for the write-up on facets. i believe it may be a first! :) the comments are especially interesting to me as the maintainer of facets, and i think it might be helpful if i quickly address some of them.


1) "Did those "rockstars" actually contribute to Facets, or had they blogged cool code that the Facets guys then incorporated into their project?" --- and the answer is "YES". there has been all levels of contribution, from direct contribution ("hey trans could you add this?"), through semi-direct contribution, (mailing list post of cool snippet, i say cool I'm going to include this in facets and they say go for it), indirect contribution (where by I see some one elses work and I use it as the basis for a more or less similar inclusion in facets), and finally absolute "lifting" (where by i come across a small general lib that's too good to leave out, thanks to OSS I can just redistribute it as part of facets). in all these cases i give _all credit_ to the originators and make no claims other than a maintainer/distributor. that fact might get a little lost sometimes b/c in addition to this, much of facets is original work by me as well, but i am completely open to every developer's desires in so far as there work is or is not included.


2) "The problem I see with facets is it's too disjointed ... I think the 'all eggs in one basket' approach of the project is a bit of a turn off." --- This is not an uncommon viewpoint, but i think it overlooks the mission of facets. facets intends to be ruby's "tertiary library", after core and after standard there's facets. so by it's very nature it is quite "broad and shallow" just like core and standard. in turn this means there are really two ways to use it. if you are just using one or two "facets" then just lift them into your project. facets is happy to support copy-and-paste reuse just as much as lib dependency. otoh, if you find yourself using a dozen core-facets, maybe a more module or two, then depending on it as a lib becomes the better option.


3) "Rubygems makes dependency handling trivial for the most part. My issue with something like Facets is that it changes the core in a broad and narrow way." --- there's the issue however, using gems to handle so many broad and narrow libs would be a nightmare, especially in terms of the ability to dig into the source. having one external dependency like facets make it much easier. also, i work very hard to keep facets in line with POLS and using a single standard lib across multiple projects makes it easier for all developers.


4) "I don't like the idea of relying on an external library for a super-duper-general method that I could roll on my own quickly enough, because it makes maintenance annoying." --- once you've rolled the same thing for the tenth time, it become a chore and you don't want to do it again, which is exactly why facets was born.


5) Lastly, "Also, I think some of the things in there totally rock. It's a cool test bed for potential RCRs. I never thought of it as something to consider using seriously in production code, though." --- each piece of facets is mostly independent of the other pieces, so each stands on its own with regards to it's level of maturity, stability, experimentation, etc. in time you become familiar with the qualities of the various parts, and of course with time all parts improve.


thanks again, hth!

Greg
2006-12-26 15:17:44
Trans, with respect to 1)
http://ruby-forum.com/topic/92265#184034


Please be careful with who you attribute,


2,3,4)


All valid points, but this boils down to personal tastes and opinions. I too view Facets as a great playground outside of core / stdlib and I think that there is plenty that people can learn by looking around in there, and that it might be a good test bed for stdlib bound features.


5)


This is the problem. I admit that like most developers, I'm guilty of the potpourri turd syndrome, but I don't want to rely on YMMV when using a number of different methods from something as broad as Facets. Regrettably, the same can be said for parts of Ruby's standard library, but I do think there is a bit more caution exercised there.


I don't think that Facets is without use, by any means. I just wanted to caution Christian from recommending it as a golden hammer, because that's really begging for troubles :)

trans
2007-01-05 17:44:51
Greg--


> Please be careful with who you attribute,


Oh I do! in fact in many cases I over do it. I credit people because they hanged one line of code! but alas, I'm not perfect and have made occasionl mistakes. In that case I may have discovered the implementation of Multiton via Florian who got it from Ara and didn't realize it.


> I too view Facets as a great playground outside of core / stdlib


Characterizing Facets as a "playground", I think is really missing the point. Yes, it can be used that way. But by far the majority of the code is pretty straight foward and quite useful. Yes, there are some edge cases, but not so many, and those parts tend to mature or go way. Facets is getting pretty stable all in all. In fact, 2.0 will be hitting the scene soon. Plus, thanks to TDD and the way Facets works, ie you only need require what you want/need and nothing more, there's really nothing wrong with using it in production.


> but I don't want to rely on YMMV when using a number of different methods


that's the nature of libraries though, isn't it? you use em or roll your own. a lot of people prefer to roll their own. that's cool.


> I don't think that Facets is without use, by any means. I just wanted
> to caution Christian from recommending it as a golden hammer, because
> that's really begging for troubles :)


not sure i understand. what troubles? I don't think anyone should consider anything a "golden hammer", personally. But tools are tools. Use em if they help.


Thanks for the discourse!

Micheal
2007-02-23 14:56:51
Very good site. Thanks for author!
Carl
2007-03-05 13:23:38
Facets are a great help in Ruby programming. I use them very often, and they make a lot of stuff easier. Facets/CORE is really helpful and I use it more than Facets/MORE.
http://carldawson.blogspot.com