Is it considered bad practice to reference accessors on the extended object from within a mixin method? A simplistic example:
module WindInstrument
def play
mouthpiece.blow #requires a mouthpiece
end
end
class Saxophone
attr_reader :mouthpiece
def initialize
#mouthpiece = Mouthpiece.new
end
include WindInstrument
end
Saxophone.new.play
In this case, I would actually just move the requirement for a mouthpiece directly to the WindInstrument module, but what about in a more complex scenario, where it really makes sense for the accessor to live on the extended object? Is this just an issue of an inappropriate separation of concerns?
Mixins feel useful for adding encapsulated behavior that doesn't require knowledge of the extended object's state. In fact, my gut tells me that a mixin shouldn't have knowledge of any state, whatsoever. If it needs knowledge of state, I would typically fall back to one of two choices:
Put the state in a class, and add it through composition, instead of through the inheritance hierarchy. My issue with this is that I know rubyists out there are creating mixins that access state, which makes for more readable, if less intuitive (to me) design.
Pass the mouthpiece as a parameter to the module. Even I can tell that this seems to muddy the design, and feels like an abomination in the ruby worldview.
Does this code bother anyone else? I know there are a lot of smart people using ruby out there, so I assume the problem is mine. What am I missing? Do I just need to chill out? What would you do?
I think it's the same as in monkey-patching: it's ok to do it, but you have to make sure that there are no alternatives first (ie. You can't modify the classes using your interface) and second, you must be very explicit about it (make sure that the docs, the comments and the interface mention that this our that method is required and will be invoked) and throw a useful error message if it isn't
Ruby's accessors are interfaces, not implementation.
For example, if you call person.height_in_feet=, you don't know what units the height is actually implemented in as an instance variable. It could be metres, feet, or cubits.
One real-life example of mixins using an accessor is the Enumerable module. Although I don't include this module in any classes I create, I'm happy with what it does. It gives you convenient methods like map and each_with_index, while staying DRY - there's only one implementation of what objects you'd access with all of the methods of the "mixee", and there's only one definition of what map does, for any object that uses Enumerable.
Related
If I have the following ruby module which implements a particular interface (apply in this case)
module FooApplier
def apply
foo
end
end
...and all other "Appliers" are classes, not modules, is it misleading to other engineers to pass FooApplier to receivers which expect the applyinterface?
Let's assume the application using FooApplier runs perfectly fine, but let's also assume that some other engineer didn't take the time to pour over every last byte of my code. If they decide to send something like .new to the FooApplier which somehow induces some subtle bug, is the onus on my design, or the engineer for making assumptions and neglecting to read my code?
The way your module is presented here, it won't work as a stand-in for a class. Let's look at a class first:
class BarApplier
def apply
bar
end
end
apply here is an instance method, so callable on instances of BarApplier, i.e. BarApplier.new.apply. This will not be possible for your module.
Unless of course apply was meant to be a class or module method, in which case your question was misleading since it then should be def self.apply.
But to answer the more general question, in a duck-typed language the sent messages are the interface. In my opinion the caller should make no assumptions about other methods being present. In your specific case, if apply is the only method in the "contract", assuming that the same entity also responds to new is invalid in my opinion.
If I have a class Salad with a method chew and I use super in it, it will call the next available chew method available going up the chain of ancestors. What if I want to "reach two levels up" (to the second available chew method going up the chain)? Is there any way to do that without adding super to the first ancestor's method?
To make this a little more concrete, suppose this is my Salad class, with a salad object:
class Salad < Food
include Almonds
include Gorgonzola
include Spinach
include Dressing
def chew
super
end
end
salad = Salad.new
The array of the ancestors would be like this:
[Salad, Dressing, Spinach, Gorgonzola, Almonds, Food, Object, Kernel, BasicObject]
If I want salad.chew to trigger the chew method in Spinach without adding super to Dressing#chew, is that possible? Is there a way to reach two levels up (in the same way that super "reaches" one level up)?
Yes, there is a way to do what you are describing, and that way is through methods #method and #instance_method, as in method = Spinach.instance_method( :chew ), which you can then bind to Salad, or to metaclasses of Salad instances, as in method.bind( Salad ). This mechanism is not as neat as using the convenience keyword super, but offers a superset of super's functionality. There are a few more details, but trust me, this way, you can do anything you want. That's the power of Ruby – you can do anything, up to the point that for the Lispiest magic, you need Ripper, and (the thus far unfinished) Sorcerer.
(For a usage example, see my other answer at Using the Object.inspect / Object.to_s on a class derived from Hash)
No, there's no way to do what you are describing (and for good reason). Any use of the "super-super" keyword which you describe would be too tightly coupled to the details of your inheritance chain (and which classes/modules in that chain implement a given method). It would be very brittle; if such a keyword existed, and you used it, then small changes like moving a method definition would very easily break things. It would also be very confusing for readers of your code.
The purpose of the super keyword is: you can take a class, subclass it, override a method, and add some new behaviors to that method, while still doing everything that the method originally did. super effectively says: "now perform the default behavior for this method". That works regardless of whether that "default" behavior is defined in the superclass, super-superclass, a module, or anywhere else.
If you are wondering how to achieve calling the chew method on all the modules, there is a better solution that is using composition. Modules are for behavior and if you think about your Salad class, you don't want it to behave like a Spinach or Almonds, you want it to be composed of them. So when you chew a salad you chew each of its components.
Is it conventional to define a subclass under it's parent class like below?
class Element
class Div < Element
end
class Paragraph < Element
end
end
Or is it more appropriate to make a module to contain the subclasses?
class Element
end
module Elements
class Div < Element
end
class Paragraph < Element
end
end
Or to create a "base" class in a module and define the subclasses within the same module?
module Element
class Base
end
class Div < Base
end
class Paragraph < Base
end
end
Or is it better to force a naming convention?
class Element
end
class DivElement < Element
end
class ParagraphElement < Element
end
It seems every library chooses a different namespacing/naming convention.
Which is the best to use?
What are the pros and cons of each?
TL;DR: The most conventional and best way to do this is with a module containing a base class and its subclasses. But let's go over everything.
There aren't many official sources on this; however, it is the style to use modules to contain libraries, code, and groups of classes.
Subclasses in Superclass
Pros:
Self-contained: The entire class system is contained under one name
Cons:
Unnatural: Who would think to look inside a superclass for a subclass?
Having the subclasses in a superclass really depends on situation. However, any benefits of this method are also achieved by the module method. But in practice, this just isn't done. Classes are here to contain methods, instance variables, class methods, etc. But classes can be thought of as a last level of nesting -- you don't have a class in a class unless it's a very specific circumstance.
The one case where I can think of this making sense is a case where the only way subclasses are used is through the superclass, for example a Formatter class that has internal subclassses like XML, PDF, etc. Let's say that you only use these classes by doing things like Formatter.new(:xml). But if we're doing this, the subclasses should be private and not accessible to the outside world anyway. And at that point, inheritance is a very C++y way and not Rubyish at all.
Base class outside module, subclasses within
Pros:
I can't think of any
Cons:
Implies Non-conected: If Element is not in the same namespace as its children, what, beyond the name tells me that it's even related?
This method is very unnatural. It makes it look as if Element has nothing to do with it's children, or if looked at differently, that it's children are internal implementation details that aren't to be dealt with. Either way it looks like shabby, sloppy naming and bad code structure planning. If I were reading code using this, I'd have to look at the contents of the Elements module to see that Element was subclassed at all -- and this isn't the most natural thing to do.
Class and subclasses in module (best solution)
Pros:
Contained: The superclass and all the Element classes are contained in one namespace, allowing them to be easily imported, required, iterated, etc. Also assists metaprogramming.
Includable: The classes can be easily includeed into any code.
Clear: There is an obvious association between Element and the subclasses. They are obviously a bundle of functionality.
Cons:
Encourages lazy naming: This does encourage you to name classes things like Base that are very ambiguous.
This is the best approach. It makes the classes a neat bundle, while still showing an obvious association and an obvious "Here, use my Div class" (as opposed to the subclasses-in-class strategy). Also, this is really helpful for metaprogramming, where having everything in a module is crucial to make things work. Finally, this works well with constructs like autoload, require_relative, include, etc. Those show that this is the way the language was designed to be used.
Force a naming convention
Pros:
Simple: No complexity here.
Removes ambiguity: Removes ambiguity from short names like Div or Para by turning them into DivElement and ParaElement.
Cons:
Archaic: Naming conventions to group classes or methods should only exist in languages that don't have a better way to do it, like C or Objective-C. C++ dropped it as soon as it got namespaces.
No programatic grouping: These naming conventions, while clear to humans, make the class structure very cloudy to metaprograming code, and make it impossible for the program to deal with the classes as a group
Pollutes global namespace: This creates many, many names in the global namespace, which is always a bad idea.
This is a very, VERY bad solution. It encorages writing sloppy, C-style code with little organization and little sense. These kinds of naming conventions should only be used in languages where there is no better solution, and Ruby has plenty of better solutions. Even defining all the classes in an array is better than a naming convention.
Note: However, if you really want to, you can define a naming convention on short names like Div or Para as long as you still keep them in a module, so that it's Elements::DivElement. However, this violates DRY, and I wouldn't suggest it.
Conclusion
So, you really have two options. Just put everything in a module:
module Elements
class Element; end
class Div < Element; end
#etc...
end
Or, put everything in a module with a naming convention:
module Elements
class Element; end
class DivElement < Element; end
#etc...
end
I sugest the former for clarity, use of standard methods, and metaprogramming reasons.
This is a problem I have faced many times - you have some shared functionality and a few different implementation classes that use it - it's natural for the shared functionality and the namespace for the implementation classes to have the same name.
I have never had a problem defining a subclass under its parent class as in your first example - except for the fact that it has sometimes confused other developers on my team. So depending on who you are working with and what their preferences are I don't think there's any problem with this approach.
I would still prefer the second approach, with a different name for the namespace, if there was a name that made sense. If there isn't, I'd use the first approach.
I would avoid using names like Base, as in my opinion this sort of generic name encourages you to just throw any old stuff in there, whereas a name that describes what the class does will (hopefully) make you think each time you add a method if it really belongs there.
And I'm really not a fan of compound names as in your naming convention example, which I justify to myself with a sort of vague feeling that it's like database normalisation - each field (or class name) should contain only one piece of information.
Anyway, I hope this helps you. I can't really draw from any sources other than my own experience (it's for you to decide if you think that's 'credible'), as I do think there's no absolute answer to this question. It is in a large part subjective.
Name space and inheritance are for different purposes. Use name space to encapsule a module within another. Use inheritance to define a module using the methods/variables/constants of another as a default.
It could happen in principle that you may want a module to both be within the name space of and inherit from the same single module, but that depends on your use case. Without discussing over a particular use case, it cannot be decided which way among the ones you presented is the best.
Does ruby have something different to other OOP languages (eg: PHP) that makes interfaces useless? Does it have some kind of replacement for this?
Edit:
Some clarifications:
In other languages (eg: PHP), you don't "need" interfaces (they are not mandatory at code level). You use them to make a contract, to improve the architecture of the software. Therefore, the affirmation 'in ruby you don't need interfaces / in other languages you need interfaces because XXX' is false.
No, mixins are not interfaces, they are a complete different thing (PHP 5.4 implements mixins). Have you even used interfaces?
Yes, PHP is OOP. Languages evolve, welcome to the present.
Well, it's a consensus that when an object is passed in Ruby it's not type-checked. Interfaces in Java and PHP are a way to affirm that an object complies to a certain contract or "type" (so something might be Serializable, Authorizable, Sequential and whatever else that you want).
However, in Ruby there is no formalized notion of a contract for which interfaces would fulfill some meaningful role as interface conformance is not checked in method signatures. See, for example, Enumerable. When you mix it into your object you are using its functionality as opposed to declaring that your object is Enumerable. The only benefit of having your object being Enumerable is that having defined each(&blk) you automatically get map, select and friends for free. You can perfectly have an object which implements all of the methods provided by Enumerable but does not mix in the module and it would still work.
For example, for any method in Ruby that expects an IO object you could feed in something that has nothing to do with an IO, and then it would explode with an error or - if you implemented your IO stub correctly - it will work just fine even though your passed object is not declared to be "IO-ish".
The idea behind that comes from the fact that objects in Ruby are not really glorified hash tables with a tag slapped onto them (which then have some extra tags that tell the interpreter or the compiler that this object has interface X therefore it can be used in context Y) but an enclosed entity responding to messages. So if an object responds to a specific message it fullfils the contract, and if it does not respond to that message - well then an error is raised.
So the absence of interfaces is compensated partially by the presence of Modules (which can contain functionality that you reach for without doing any type promises to the caller/consumer) and partially by the tradition of message-passing as opposed to typed dicts.
You should watch some presentations by Jim Weirich since he touches on the subject extensively.
This question is kind of open-ended, but here is my take:
The purpose of an interface declaration is two things:
Declare to your future self or colleagues what methods this class must have
Declare to your computer what methods this class must have
If we take the second purpose first, Ruby source code is never compiled, so there is never an option to verify the conformance to the interface declaration and warn the developer of any failure to conform. This means that if Ruby had some built-in interface support, it wouldn't have an option to verify the conformance until runtime, where the application will crash anyway, because of the missing implementation.
So back to the first purpose. Code readability. This could make sense and a formal Ruby convention of specifying interfaces might be helpful. For now, you would probably communicate this using comments or specs or - as I would probably prefer - a declarative module inclusion. E.g.
module Shippable
# This is an interface module. If your class includes this module, make sure it responds to the following methods
# Returns an integer fixnum representing weight in grams
def weight
raise NotImplementedError.new
end
# Returns an instance of the Dimension class.
def dimensions
raise NotImplementedError.new
end
# Returns true if the entity requires special handling.
def dangerous?
raise NotImplementedError.new
end
# Returns true if the entity is intended for human consumption and thereby must abide by food shipping regulations.
def edible?
raise NotImplementedError.new
end
end
class Product
include Shippable
end
A way of enforcing this interface would be by creating a spec that creates an instance of every class that includes the Shippable module, calls the four methods and expects them to not raise NotImplementedError.
I'm a 'Ruby person', and I would like interfaces, or something like them.
Not to enforce a contract - because enforcing anything isn't very Ruby, and kind of defeats the point of a dynamic language, and anyway there's no "compilation" step to enforce it at - but to document contracts that client subclasses can choose to conform to (or not, although if they choose not to they can't complain if the code doesn't work).
When I'm faced with this problem, ie, when I'm writing a class or module I expect subclasses to provide methods for, I usually document the methods I expect subclasses to provide like this:
module Enumerable
def each
raise NotImplementedError, "Subclasses must provide this method"
end
end
It's not ideal, but it's a reasonably rare case and it works for me.
As ruby is duck-typed, no separate interface is needed, but the objects only need to implement the common methods. Look at the "classic" example below:
class Duck
def move
"I can waddle."
end
end
class Bird
def move
"I can fly."
end
end
animals = []
animals << Duck.new
animals << Bird.new
animals.each do |animal|
puts animal.move
end
In this example, the "interface" is the move method, which is implemented by both the Duck and the Bird class.
I believe it's because Ruby is dynamically typed whereas other languages are statically typed. The only reason you'd need to use an interface in PHP is when you use type hinting when passing objects around.
Ruby is very dynamic and duck-typed. Wouldn't that make interfaces kind of useless or overkill? Interfaces force classes to have certain methods available at compile time.
Review this too:
http://en.wikipedia.org/wiki/Duck_typing
Depends what you mean by interface.
If by interface you mean a concrete object that exists in your language that you inherit from or implement then no you don't use interfaces in a language like ruby.
If you mean interface as in objects have some well documented interface then yes of course, objects still have a well documented interfaces, they have attributes and methods that you expect to be there.
I'd agree that interfaces are something that exists in your mind and the documentation and not in the code as an object.
I was reading up on Ruby, and learned about its mixins pattern, but couldn't think of many useful mixin functionality (because I'm not used to thinking that way most likely). So I was wondering what would be good examples of useful Mixin functionality?
Thanks
Edit: A bit of background. I'm Coming from C++, and other Object languages, but my doubt here is that Ruby says it's not inheriting mixins, but I keep seeing mixins as Multiple inheritance, so I fear I'm trying to categorize them too soon into my comfort zone, and not really grok what a mixin is.
They are usually used to add some form of standard functionality to a class, without having to redefine it all. You can probably think of them a bit like interfaces in Java, but instead of just defining a list of methods that need to be implemented, many of them will actually be implemented by including the module.
There are a few examples in the standard library:
Singleton - A module that can be mixed into any class to make it a singleton. The initialize method is made private, and an instance method added, which ensures that there is only ever one instance of that class in your application.
Comparable - If you include this module in a class, defining the <=> method, which compares the current instance with another object and says which is greater, is enough to provide <, <=, ==, >=, >, and between? methods.
Enumerable - By mixing in this module, and defining an each method, you get support for all the other related methods such as collect, inject, select, and reject. If it's also got the <=> method, then it will also support sort, min, and max.
DataMapper is also an interesting example of what can be done with a simple include statement, taking a standard class, and adding the ability to persist it to a data store.
Well the usual example I think is Persistence
module Persistence
def load sFileName
puts "load code to read #{sFileName} contents into my_data"
end
def save sFileName
puts "Uber code to persist #{#my_data} to #{sFileName}"
end
end
class BrandNewClass
include Persistence
attr :my_data
def data=(someData)
#my_data = someData
end
end
b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
b.load "MyFile.secret"
Imagine the module is written by a Ruby ninja, which persists the state of your class to a file.
Now suppose I write a brand new class, I can reuse the functionality of persistence by mixing it in by saying include ModuleILike. You can even include modules at runtime. I get load and save methods for free by just mixing it in. These methods are just like the ones that you wrote yourself for your class. Code/Behavior/Functionality-reuse without inheritance!
So what you're doing is including methods to the method table for your class (not literally correct but close).
In ruby, the reason that Mixins aren't multiple-inheritance is that combining mixin methods is a one time thing. This wouldn't be such a big issue, except that Ruby's modules and classes are open to modification. This means that if you mixin a module to your class, then add a method to the module, the method will not be available to your class; where if you did it in the opposite order, it would.
It's like ordering an ice-cream cone. If you get chocolate sprinkles and toffee bits as your mixins, and walk away with your cone, what kind of ice cream cone you have won't change if someone adds multicolored sprinkles to the chocolate sprinkles bin back at the ice-cream shop. Your class, the ice cream cone, isn't modified when the mixin module, the bin of sprinkles is. The next person to use that mixin module will see the changes.
When you include a module in ruby, it calls Module#append_features on that module, which add a copy of that module's methods to the includer one time.
Multiple inheritance, as I understand it, is more like delegation. If your class doesn't know how to do something, it asks its parents. In an open-class environment, a class's parents may have been modified after the class was created.
It's like a RL parent-child relationship. Your mother might have learned how to juggle after you were born, but if someone asks you to juggle and you ask her to either: show you how (copy it when you need it) or do it for you (pure delegation), then she'll be able at that point, even though you were created before her ability to juggle was.
It's possible that you could modify a ruby module 'include' to act more like multiple inheritance by modifying Module#append_features to keep a list of includers, and then to update them using the method_added callback, but this would be a big shift from standard Ruby, and could cause major issues when working with others code. You might be better creating a Module#inherit method that called include and handled delegation as well.
As for a real world example, Enumerable is awesome. If you define #each and include Enumerable in your class, then that gives you access to a whole host of iterators, without you having to code each and every one.
It is largely used as one might use multiple inheritance in C++ or implementing interfaces in Java/C#. I'm not sure where your experience lies, but if you have done those things before, mixins are how you would do them in Ruby. It's a systemized way of injecting functionality into classes.