I'm trying to wrap my head around Ruby, and one thing I'm struggling with is the lack of interface/abstract class support. From googling about, the response I continuously see to abstract class related Ruby questions is "You're thinking in Java. Ruby doesn't work that way"
So, how would one work in Ruby without interfaces/abstract classes?
For example, in Java I might create an abstract class "book", with subclasses "novel", "textbook", and "journal". There is a lot of common functionality that I throw in 'book', but I don't want it to be directly accessible - a book must be either a novel, textbook or journal.
In ruby, how would I write out that sort of functionality?
I am also Ruby starter. From my understanding, there is a closer rival for abstract classes in ruby. that is module. you can't create any instances of module but you can include with another class. So a target class will get the whole functionality of parent
module Log
def write
//blah
end
end
class EventLog
include Log
def Prepare
end
end
In statically typed languages like java/C# , Interfaces enforce the classes to have all the methods at compile time. Since Ruby is dynamic, there is no meaning in it.
For more clarity, check these posts why dynamic languages don't require interfaces..
why-dont-we-require-interfaces-in-dynamic-languages
why-do-dynamic-languages-like-ruby-and-python-not-have-the-concept-of-interfaces
Cheers
there are ways to implement this type of thing, including abstract_type gem. While ruby doesn't require it and has mixins, i think there are cases, like adapters, where you'd want to secure your interface to a set of objects with something more explicit.
also, check out http://metabates.com/2011/02/07/building-interfaces-and-abstract-classes-in-ruby/
Related
I read a blog post that recommends namespacing your monkey patches so they can be easily viewed and included.
For example:
module CoreExtensions
module DateTime
module BusinessDays
def weekday?
!sunday? && !saturday?
end
end
end
end
Would go in the: lib/core_extensions/class_name/group.rb file.
It can be included in the DateTime class with the Module#include instance method (which a class inherits because a Class is a Module)
# Actually monkey-patch DateTime
DateTime.include CoreExtensions::DateTime::BusinessDays
My question is where do the include statements go? Is there a convention?
For example:
I have the following monkey patches:
# http://www.justinweiss.com/articles/3-ways-to-monkey-patch-without-making-a-mess/
module CoreExtensions
module String
module Cases
def snakecase
return self if self !~ /[A-Z]+.*/
# http://rubular.com/r/afGWPWLRBB
underscored = gsub(/(.)([A-Z])/, '\1_\2')
underscored.downcase
end
def camelcase
return self if self !~ /_/ && self =~ /[A-Z]+.*/
split('_').map{ |e| e.capitalize }.join
end
end
end
end
That live inside the lib/core_extensions/string/cases.rb file.
Where should I put my String.include CoreExtensions::String::Cases statement?
Also to be clear this is just a ruby project, does that make a difference?
I've tried putting it inside lib/devify.rb
require 'devify/version'
require 'devify/some_dir'
require 'devify/scaffold'
require 'devify/tree_cloner'
require 'devify/renderer'
require 'devify/project'
require 'devify/tasks/some_task'
require 'devify/tasks/bootstrap'
require 'core_extensions/string/cases'
module Devify
String.include CoreExtensions::String::Cases
end
This works and it makes sense why it works. It's because my entire app lives inside the Devify module or namespace.
This way is also good because I'm not polluting the global namespace correct? Because I'm only monkey patching Strings that live inside Devify?
Just not sure not if this is the right way to go about it.
It doesn't matter where you put the include call.
Calling String.include will always monkey patch the one String class that is used by all the strings in the entire object space. So best put the instruction at the top level as to not mislead readers of the code.
Monkey patching is always global.
It is a powerful feature and can be used for good.
If you are authoring a gem be aware that you're sharing a global namespace with others. The same is also true for top-level modules and even the gem name though. Shared namespaces are just a reality of shared code.
If you are looking for lexically scoped monkey patches look into the new refinement feature that was introduce with Ruby 2.
Refinements are an idea taken from Smalltalk's class boxes. Refinements are not without their own issues though, for example they lack support for introspection and reflection. Thus essentially making them stealth and unfit for production use.
If you are looking to limit the monkey patches to some string object only, consider either subclassing String or calling extend on an instance.
Although ruby offers many ways of changing the content of a class or a method dynamically, the monkey patching can lead to big problems and strange bugs. I read this post (http://www.virtuouscode.com/2008/02/23/why-monkeypatching-is-destroying-ruby/) about why it´s a bad idea to use monkey-patching.
In summary, many things that he says make sense. When you create a monkey-patching, you are assuming that it will only works at that project, and, maybe you can create collisions and unprevisible side-effects when more libraries with similar purposes are put together.
There are cases where the benefits of the monkey-patching were awesome, like ActiveSupport way of dealing with dates manipulation by monkey-patching the Fixnum class with the ago or from_now methods, or as the method to_json. However, monkey patching should be avoided.
The point is: Ruby is an object-oriented language, and you can achieve your objectives using object composition, or any other patterns. Monkey-patching, at some way, leads you in the opposite direction of object oriented philosophy, since you add more responsibilities to an pre-existent class and increases it's public interface to serve a new funcionallity.
Besides, it's not explicit the behavior of that class and the public methods available. You cannot know, by looking at the class definition, what it makes and what is it's role at the system, and how it interact with other objects. It makes a simple task much more harder at the end.
Monkey patching makes everything much more smaller and simpler, apparently, but avoiding it makes your code much more maintanable, easier to debug, read and test, and much more elegant, since it is compliant to the "OOP" patterns.
I'm very new to this and I try to google it, but I can't seem to really figure out how this really works so I am here asking this question :(...
It's actually quite simple, I just need a syntax of this:
Class Player <- An abstract super class representing a player object
Classes Human and Computer <- Classes extending the super class Player
Dat's it! It should be a simple one, you guys can either give me a direct translation of the description into Ruby syntax or some other examples to help me.
One more question just in case, for a abstract super class, is defining a instance method the same as a normal class? Because normal class usually goes like:
def Method1(parameters)
blah blah blah;
end
Thx in advance!
In Ruby you don't have the keyword abstract to defined abstract classes. If you need to encapsulate functionality that is intended to be shared among different classes, you can extract that into a module, and mix it in with the classes.
For instance:
module Player
# shared functionality
end
class Human
include Player
end
class Computer
include Player
end
This works well since abstract, as in disassociated from any specific instance, is just construct that can be achieve in many different ways. Different language choose to be more explicit about it, in ruby is more implicit.
there is already many questions on that:
How to implement an abstract class in ruby?
in a short, there is no Abstract classes in Ruby, but you could emulate em if you need so
I am just starting Ruby and learning the concept of modules. I understand that one use of modules is to better organize your code and avoid name clashes. Let's say I have bunch of modules like this (I haven't included the implementation as that's not important)
:
module Dropbox
class Base
def initialize(a_user)
end
end
class Event < Base
def newFile?
end
def newImage?
end
end
class Action < Base
def saveFile(params)
end
end
end
and another module:
module CustomURL
class Base
def initialize(a_user, a_url, a_method, some_args, a_regex)
end
end
class Event < Base
def initialize(a_user, a_url, a_method, some_args, a_regex)
end
def change?
end
end
class Action < Base
def send_request(params)
end
end
end
I am going to have a bunch of these modules (10+, for gmail, hotmail, etc...). What I am trying to figure out is, is this the right way to organize my code?
Basically, I am using module to represent a "service" and all services will have a common interface class (base for initializing, action for list of actions and event for monitoring).
You are defining families of related or dependent classes here. Your usage of modules as namespaces for these families is correct.
Also with this approach it would be easy to build abstract factory for your classes if they had compatible interface. But as far as I see this is not the case for current classes design: for example Dropbox::Event and CustomURL::Event have completely different public methods.
You can reevaluate design of your classes and see if it is possible for them to have uniform interface so that you can use polymorphism and extract something like BaseEvent and BaseAction so that all Events and Actions will derive from these base classes.
Update: As far as you define services, it might be useful to define top-level module like Service and put all your classes inside this module. It will improve modularity of your system. If in the future you would refactor out some base classes for your modules services, you can put them in the top-level namespace. Then your objects will have readable names like these:
Service::Dropbox::Event
Service::Dropbox::Action
Service::CustomURL::Event
Service::CustomURL::Action
Service::BaseEvent
Service::BaseAction
I have some similar code at work, only I'm modeling networking gear.
I took the approach of defining a generic class with the common attributes and methods, including a generic comparator, and then sub-class that for the various models of hardware. The sub-classes contain the unique attributes for that hardware, plus all the support code necessary to initialize or compare an instance of that equipment with another.
As soon as I see the need to write a method similar to another I wrote I think about how I can reuse that code by promoting it to the base-class. Often this involves changing how I am passing parameters, and instead of using formal parameters, I end up using a hash, then pulling what I need from it, keeping the method interface under control.
Because you would have a lot of sub-classes to a base class, it's important to take your time and think out how that base-class should work. As you add sub-classes the task of refactoring the base will get harder because you will have to change other sub-classes. I always find I go down some blind-alleys and have to back up a bit, but as the class matures that should happen less and less.
As you will notice soon, there is no 'right way' of organizing code.
There are subtle differences in readability that are mostly subjective. The way you are organizing classes is just fine for releasing your code as a gem. It usually isn't needed in code that won't be included in other peoples projects, but it won't hurt either.
Just ask yourself "does this make sense for someone reading my code who has no idea what my intention is?".
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.