From: Brian Candler Date: 2009-01-29T22:44:48+09:00 Subject: Re: proper use of classes David A. Black wrote: > One way to get a sense of how classes are used (and useful) is to > consider the Ruby language itself. In any language, you need to be > able to have multiple filehandles open. In Ruby, that need is > addressed by modeling each filehandle as an instance of File. The > class is, so to speak, the dispatch station, where requests for new > filehandles are fielded. But the class itself does not attach itself > to a particular file, since that would severely limit you. Good example. Similarly, methods which act on the filesystem, but don't need to maintain their own state, are class methods: e.g. File.exist?, File.rename, File.delete Another example you could consider is an XML parser. You could write this as a standalone method in a module: result = XMLParser.parse(source) That would parse the source from start to end in one operation. It might return an object representing the results, or it could yield each element to a block that you parse. But once the parsing is done, it's done, and there's no need to remember anything. One reason you might want to create an *instance* of a parser is to remember options which will be re-used when parsing multiple documents: parser = XMLParser.new(:arrays => true, :strip_space => false) res1 = parser.parse(source1) res2 = parser.parse(source2) A completely different reason is so that the parser object can be attached to a particular document that you are parsing. This would allow the parsing operation to be spread out over time, and you could ask it when you like for the next tag - a "pull parser" parser = XMLParser.new(source) e1 = parser.next_element e2 = parser.next_element ... Here, the object instance keeps a reference to the source object, and keeps track of the parsing state (e.g. stack of open tags) So the need to keep state is driven by the user's requirements. If you don't need to keep state, then don't. > I've been thinking only in terms of functions, things my program does, > and not things it works on or with. There is absolutely nothing wrong with this, and if you follow it to its conclusion you will end up with functional programming, where every output is a product of its inputs only. This is how many computer science courses introduce programming. For example, if you look at data structures in Erlang, generally you pass in the old data structure as an argument and receive a new one as a result: add_element(Element, Set1) -> Set2 There's no "set object" as such, just some data structure representing a set, which is passed in and returned. In Ruby, if you make an object representing a set, the first argument is implicitly 'self', so there's no need to pass in Set1. Also, your method may choose to return a new object, or to modify its own state. Note that whilst you can demonstrate functional programming techniques with Ruby, the language isn't really geared up to support them fully. -- Posted via http://www.ruby-forum.com/.