Using design pattern with modules - ruby

As I understand: in Ruby, we use modules instead of classes when we don't need a state; if it's just a function that takes an input an produces an output.
Some design patterns depend on inheritance, like the template design pattern.
I am making a crawling library that takes a link as an input and produces an object containing the data.
It don't need a state so a module seems to be suitable for me instead of a class. I also need to use the template design pattern as I am using different algorithms to produce data with the same structure. I need to use inheritance to implement template design pattern, but I don't need a state; it just returns the data from the website.
Is implementing a design pattern a good reason to use classes (for inheritance)? What is the best practice in such cases?

In Ruby, we use modules instead of classes when we don't need a state; if it's just a function that takes an input an produces an output.
That's one use of modules. Another use of modules is to provide what other languages would call "traits", sets of functionality which can be plugged into any class without inheritance. This can and often does include storing state.
Be sure to remain flexible, Ruby is a very flexible language.
It don't need a state so a module seems to be suitable for me instead of a class. I also need to use the template design pattern as I am using different algorithms to produce data with the same structure.
Design patterns provide a pattern for solving certain general problems, not a set of rules which must be strictly adhered to. Many were written with C++ or Java in mind, extremely class-centric languages, and require some adapting to other languages.
In your case, all that matters is the interface remains the same. Rather than creating a whole abstract class, all you need to do is define an interface. Some languages have formal interfaces, like Rust or Java. Ruby does not. Instead it uses duck-typing. Basically if it has the methods you need and says it works like you need, use it.
module DoThatThing
module ThisProvider
def link_to_object(link)
...code to convert a link to ThisProvider into an object...
return object
end
end
module ThatProvider
def link_to_object(link)
...code to convert a link to ThatProvider into an object...
return object
end
end
end
Now it doesn't matter if you have DoThatThing::ThisProvider or DoThatThing::ThatProvider, you use them the same.
obj = provider_module.link_to_object(link)
You can, if you really want to, implement formal abstract modules in Ruby, but in Ruby it's generally a wasted effort and very much goes against how one does things in Ruby (in other languages, absolutely create an interface).
Instead, enforce this with testing. RSpec shared examples, or a similar feature of your testing system, are a good way to do that. You write one set of tests which should work for any implementation of DoThatThing and run them for all implementations of DoThatThing.
RSpec.shared_examples 'DoThatThing' do
...shared tests for any DoThatThing...
end
RSpec.describe DoThatThing::ThisProvider do
include_examples "DoThatThing"
...tests specific to ThisProvider...
end
RSpec.describe DoThatThing::ThatProvider do
include_examples "DoThatThing"
...tests specific to ThatProvider...
end

Related

Is there a gem that provides support to detect changes to native ruby type instances?

Although I agree that extending native types and objects is a bad practice, inheriting from them should not be.
In a supposedly supporting gem (that I could not find), the way that the native types were to be used would be as follows:
require 'cool-unkown-light-gem'
class MyTypedArray < CoolArray # would love to directly < Array
def initialize(*args)
super(*args)
# some inits for DataArray
#caches_init = false
end
def name?(name)
init_caches unless !#caches_init
!!#cache_by_name[name]
end
def element(name)
init_caches unless !#caches_init
#cache_by_name[name]
end
private
# overrides the CoolArray method:
# CoolArray methods that modify self will call this method
def on_change
#caches_init = false
super
end
def init_caches
return #cache_by_name if #caches_init
#caches_init = true
#cache_by_name = self.map do |elem|
[elem.unique_name, elem]
end.to_h
end
end
Any method of the parent class not overridden by the child class that modifies self would call, let's say (in this case), the on_change function. Which would allow to do not have to re-define every single one of those methods to avoid losing track on changes.
Let's say the MyTypedArray would array Foo objects:
class Foo
attr_reader :unique_name
def initialize(name)
#unique_name = name
end
end
a short example of the expected behaviour of its usage:
my_array = MyTypedArray.new
my_array.push( Foo.new("bar") ).push( Foo.new("baz") )
my_array.element("bar").unique_name
# => "bar"
my_array.shift # a method that removes the first element from self
my_array.element("bar").unique_name
# => undefined method `unique_name' for nil:NilClass (NoMethodError)
my_array.name?("bar")
# => false
I understand that we should search for immutable classes, yet those native types support changes on the same object and we want a proper way to do an inheritance that is as brief and easy as possible.
Any thoughts, approaches, or recommendations are more than welcome, of course. I do not think I am the only one that have thought on this.
The reason why I am searching for a maintained gem is because different ruby versions may offer different supported methods or options for native types / classes.
[Edit]
The aim of the above is to figure out a pattern that works. I could just follow the rules and suggestions of other posts, yet would not get things work the way I am intended and when I see it proper (a coding language is made by and for humans, and not humans made for coding languages). I know everyone is proud of their achievements in learning, developing and making things shaped in a pattern that is well known in the community.
The target of the above is because all the methods of Array are more than welcome. I do not care if in the version 20 of Ruby they remove some methods of Array. By then my application will be obsolete or someone will achieve the same result in far less code.
Why Array?
Because the order matters.
Why an internal Hash?
Because for the usage I want to make of it, in overall, the cost of building the hash compensates the optimization it offers.
Why not just include Enumerable?
Because we just reduce the number of methods that change the object, but we do not actually have a pattern that allows to change #caches_init to false, so the Hash is rebuilt on next usage (so same problem as with Array)
Why not just whitelist and include target Array methods?
Because that does not get me where I want to be. What if I want anyone to still use pop, or shift but I do not want to redefine them, or even having to bother to manage my mixins and constantly having to use responds_to?? (perhaps that exercise is good to improve your skills in coding and read code from other people, but that is not what it should be)
Where I want to be?
I want to be in a position that I can re-use / inherit any, I repeat, any class (no matter if it is native or not). That is basic for an OOP language. And if we are not talking about an OOP language (but just some sugar at the top of it to make it appear as OOP), then let's keep ourselves open to analyse patterns that should work well (no matter if they are odd - for me is more odd that there are no intermediate levels; which is symptom of many conventional patterns, which in turn is symptom of poor support for certain features that are more widely required than what is accepted).
Why should a gem offer the above?
Well, let's humble it. The above is a very simple case (and even though not covered). You may gain in flexibility at some point by using what some people want to call the Ruby way. But at a cost when you move to bigger architectures. What if I want to create intermediate classes to inherit from? Enriched native classes that boost simple code, yet keeping it aligned with the language. It is easier to say this is not the Ruby way than trying to make the language closer to something that escalates well from the bottom.
I am not surprised that Rails and Ruby are almost "indistinctly" used by many. Because at some point, without some Rails support, what you have with Ruby is a lot of trouble. As, consequently, I am not surprised that Rails is so maintained.
Why should I redefine a pop, or a last, or first methods? For what? They are already implemented.
Why should I whitelist methods and create mixins? is that a object or method oriented programming?
Anyway... I do not expect anyone to share my view on this. I do see other patterns, and I will keep allowing my mind to find them. If anyone is open enough, please, feel free to share. Someone may criticize the approach and be right, but if you got there is because it worked.
To answer your question as it is written, no, there is no gem for this. This is not a possibility of the language, either in pure Ruby or in C which is used internally.
There is no mechanism in detect when self is changed, nor any way to detect if a method is pure (does not change self) or impure (does change self). It seems you want a way to "automatically" be able to know when a method is one or the other, and that, to put simply, is just not possible, nor is it in any language that I am aware of.
Internally (using your example) an Array is backed by a RArray structure in C. A struct is simple storage space: a way to look at an arbitrary block of memory. C does not care how you choose to look at memory, I could just as easily cast the pointer of this struct and say it is a now a pointer to an array of integers and change it that way, it will happily manipulate the memory as I tell it to, and there is nothing that can detect that I did so. Now add in the fact that anyone, any script, or any gem can do this and you have no control over it, and it just shows that this solution is fundamentally and objectively flawed.
This is why most (all?) languages that need to be notified when an object is changed use an observer pattern. You create a function that "notifies" when something changes, and you invoke that function manually when needed. If someone decides to subclass your class, they need only continue the pattern to raise that function if it changes the object state.
There is no such thing as an automatic way of doing this. As already explained, this is an "opt-in" or "whitelist" solution. If you want to subclass an existing object instead of using your own from scratch, then you need to modify its behavior accordingly.
That said, adding the functionality is not as daunting as you may think if you use some clever aliasing and meta-programming with module_eval, class_eval or the like.
# This is 100% untested and not even checked for syntax, just rough idea
def on_changed
# Do whatever you need here when object is changed
end
# Unpure methods like []=, <<, push, map!, etc, etc
unpure_methods.each do |name|
class_eval <<-EOS
alias #{name}_orig #{name}
def #{name}(*args, &block)
#{name}_orig(*args, &block)
on_changed
end
EOS
end

Is ruby a pure object oriented programming language even though it doesn't support multiple inheritance? Please Explain

Is ruby a pure object oriented programming language even though it doesn't support multiple inheritance? If so how?, please explain.
I know that to an extent substitutes the lack of multiple inheritance by allowing one to include multiple modules within a class.
Also, I'm not sure of all of the prerequisites of a pure OOP Language. From this article, they mention
a Ruby class can have only one method with a given name (if you define
a method with the same name twice, the latter method definition
prevails..
So does it mean that Ruby doesn't support Overloading methods. If so, it still can qualify as a pure OOP Lanaguage ? If so, kindly explain the reason behind this as well.
Thank you.
There are several different families of object-oriented languages. If you're thinking of multiple inheritance and method overloading, you're probably coming from a C++ mindset where these things are taken for granted. These conventions came from earlier languages that C++ is heavily influenced by.
Ruby doesn't concern itself with the type of objects, but rather the methods they're capable of responding to. This is called duck typing and is what separates Smalltalk-inspired languages like Ruby from the more formal Simula or ALGOL influenced languages like C++.
Using modules it's possible to "mix in" methods from various sources and have a sort of multiple inheritance, but strictly speaking it's not possible for a class to have more than one immediate parent class. In practice this is generally not a big deal, as inheritance is not the only way of adding methods.
Method overloading is largely irrelevant in Ruby because of duck-typing. In C++ you might have various methods for handling string, int or float types, but in Ruby you'd have one that calls to_f on whatever comes in and manipulates it accordingly. In this sense, Ruby methods are a lot more like C++ templates.
If multiple inheritance were the only "symptom" of a OOP language, then neither would Java, C#, Python, and many more be OOP languages.
What makes a language object-oriented in the first place are naturally objects. Everything is an object in ruby. The whole language is built on the concept of objects and data. Different objects can "communicate" between each other, you can encapsulate data, etc.
Take a look at this resource: Definitions for ObjectOriented.
In the first place, the problem of multiple inheritance makes sense only for an object oriented language. The very question of asking about multiple inheritance with Ruby itself proves that Ruby is an object oriented language.

Ruby class loading mechanism

I'm beginning with the Ruby programming language and I'm interested in understanding it in depth before I start studding the Rails framework.
I'm currently a little disappointed because everybody seams to care only about the Rails framework, and other aspects of the language are just not discussed in depth, such as its class loading mechanism.
Considering that I'm starting by doing some desktop/console experiments, I would like to better understand the following matters:
Is it a good practice to place each Ruby class in a separate Ruby file? (*.rb)
If I have, let's say .. 10 classes .. and all of them reference each other, by instantiating one another and calling each other's methods, should I add a 'require' statement in each file to state which classes are required by the class in that file? (just like we do with 'import' statements in each Java class file?)
Is there a difference in placing a 'require' statement before or after (inside) a class declaration?
What could be considered a proper Ruby program's 'entry point'? It seams to me that any .rb script will suffice, since the language doesn't have a convention like C or Java where we always need a 'main' function of method.
Is class loading considered a 'phase' in the execution of a Ruby program? Are we supposed to load all the classes that are needed by the application right at the start?
Shouldn't the interpreter itself be responsible for finding and loading classes as we run the code that needs them? By searching the paths in the $LOAD_PATH variable, like Java does with its $CLASSPATH?
Thank you.
In general terms, it's a good practice to create a separate .rb file for each Ruby class unless the classes are of a utility nature and are too trivial to warrant separation. An instance of this would be a custom Exception derived class where putting it in a separate file would be more trouble than its worth.
Tradition holds that the name of the class and the filename are related. Where the class is called ExampleClass, the file is called example_class, the "underscored" version of same. There are occasions when you'll buck this convention, but so long as you're consistent about it there shouldn't be problems. The Rails ActiveSupport auto-loader will help you out a lot if you follow convention, so a lot of people follow this practice.
Likewise, you'll want to organize your application into folders like lib and bin to separate command-line scripts from back-end libraries. The command-line scripts do not usually have a .rb extension, whereas the libraries should.
When it comes to require, this should be used sparingly. If you structure your library files correctly they can all load automatically once you've called require on the top-level one. This is done with the autoload feature.
For example, lib/example_class.rb might look like:
class ExampleClass
class SpecialException < Exception
end
autoload(:Foo, 'example_class/foo')
# ...
end
You would organize other things under separate directories or files, like lib/example_class/foo.rb which could contain:
class ExampleClass::Foo
# ...
end
You can keep chaining autoloads all the way down. This has the advantage of only loading modules that are actually referenced.
Sometimes you'll want to defer a require to somewhere inside the class implementation. This is useful if you want to avoid loading in a heavy library unless a particular feature is used, where this feature is unlikely to be used under ordinary circumstances.
For example, you might not want to load the YAML library unless you're doing some debugging:
def debug_export_to_yaml
require 'yaml'
YAML.dump(some_stuff)
end
If you look at the structure of common Ruby gems, the "entry point" is often the top-level of your library or a utility script that includes this library. So for an example ExampleLibrary, your entry point would be lib/example_library.rb which would be structured to include the rest on demand. You might also have a script bin/library_tool that would do this for you.
As for when to load things, if there's a very high chance of something getting used, load it up front to pay the price early, so called "eager loading". If there's a low chance of it getting used, load it on demand, or leave it "lazy loaded" as it's called.
Have a look at the source of some simple but popular gems to get a sense of how most people structure their applications.
I'll try to help you with the first one:
Is it a good practice to place each Ruby class in a separate Ruby file? (*.rb)
It comes down to how closely related those classes are. Let's see a few examples. Look this class: https://github.com/resque/resque/blob/master/lib/resque.rb
, it "imports" the functionality of several classes that, although they work together, they are not closely related to be bundled together.
On the other hand, take a look at this module: https://github.com/resque/resque/blob/master/lib/resque/errors.rb. It bundles 5 different classes, but these do belong together since they are all essentially representing the same.
Additionally, from a design standpoint a good rule of thump could be asking yourself, who else is using this class/ functionality (meaning which other parts of the code base needs it)?
Let's say that you want to represent a Click and WheelScroll performed by a Mouse. It would make more sense in this trivial example, that those classes be bundled together:
module ComputerPart
class Mouse; end
class WheelScroll; end
class Click; end
end
Finally, I would recommend that you peruse the code of some of these popular projects to kind of get the feeling how the community usually make these decisions.
1.) I follow this practice, but it is not necessary, you can put a bunch of classes in one file if you want.
2.) If the classes are in the same file, no, they will all be accessible when you run the script. If they are in separate files then you should require them, you can also require the entire directory that the file(self) is in.
3.)Yes, it should be at the top of the file.
4.) In ruby everything descends from the Main object, the Interpreter just handles creating it for you. If you are writing OO ruby and not just scripts, then the entry point will be the init method of the first class you call.
5.) Yes, before the program runs it loads up all the dependencies.
6.) I think it does this, all you have to do is require the proper files at the top of the files, after that you can use them as you wish without having to implicitly load them again.

What are advantages and disadvantages of dynamic type in Ruby?

Let's say I have a class called Tool:
class Tool
def initialize( name, weight )
#name = name
#weight = weight
end
attr_reader :name, :weight
attr_writer :name, :weight
def to_s
name + " " + weight
end
end
But this Tool can be a person if I want to:
hammer = Tool.new( "Hammer", 14.5 )
pp = Tool.new( "first", "last" )
It's flexible because I can create one type and use for multiple purposes. However, if user accidentally makes a typo, it will definitely lead to wrong data type, how can we track the issue?
What are the advantages and disadvantages of this idea?
Ruby is not loosely typed at all. Quite the contrary, it's very strongly typed. However it is also dynamically typed (as opposed to statically typed, such as C++ and Java). You should do some reading on the differences. PHP is an example of a loosely typed language.
And to answer your question, dynamically-typed languages such as Ruby and Python are very difficult to write with any amount of complexity without employing Test-Driven Development. That is, trying your hardest to write tests first to explain expectations and to define your classes and APIs such that people will know how to use them simply by using common sense. If you're really worried about clients passing invalid types to your methods, you can always type-check and throw exceptions if the types are incorrect. However, this is not typically done system-wide.
Static typing in most languages (well, Java & friends, I'm not considering the Haskell family here) makes programs verbose and over-constrains them, with little return at the design level. What's important when establishing a relation between two objects is what role they play and responsibilities they have, not what their type is, so static typing makes you think at the wrong level.
About robustness, just like null pointers, type errors typically cause catastrophic failure rather quickly, so they will never go undetected for long. So IMHO the class of errors prevented by static typing is not that interesting. On the other hand, anyone could write Tool.new( "Hammer", -42 ) which would be correct typewise, but the negative weight would probably lead to very strange behavior without failure. That's because that argument's role is a weight, which is never negative, and you cannot express that with a simple numeric type. So what's really needed at design time is not static types, but validations or contracts as in Eiffel.
Now, consider unanticipated software evolution: you want to integrate support for SI units. Do you see why the design decision of statically typing that parameter to number now looks like a premature one? In a dynamically typed system it's easier to craft a new object that knows arithmetic but takes unit conversions into account, and to use that directly in place of numbers in the existing code.
Of course, static types have documentation value, and dynamically typed languages require some discipline in that area, namely clear naming, good tests, good comments... but none of those are superfluous with static typing anyway.
I wouldn't describe that as loosely or dynamically typing - rather it's using one class for two distinct purposes. In general, you shouldn't create a class that general to store completely disparate sets of data.
The disadvantages of your method are as you mentioned - user confusion and potential bad data. You should probably create a second class, Person, to handle your objects that are people. It eliminates confusion and has zero potential for users to make a typo and create the wrong data type.
[edit]
And to prevent users from entering bad data, you could modify your weight= method that is created by your attr_writer like so:
def weight= value
#weight = value.to_i # only store integers
end
Or check that the string entered is actually a number and raise an exception if not.

Does Ruby have a Metaobject protocol and if not, is it possible to implement one?

Pardon my ignorance, but What is a Metaobject protocol, and does Ruby have one? If not, is it possible to implement one for Ruby? What features might a Metaobject protocol possess if Ruby was to have one?
What is a Metaobject protocol?
The best description I've come across is from the Class::MOP documentation:
A meta object protocol is an API to an object system.
To be more specific, it abstracts the components of an object system (classes, object, methods, object attributes, etc.). These abstractions can then be used to inspect and manipulate the object system which they describe.
It can be said that there are two MOPs for any object system; the implicit MOP and the explicit MOP. The implicit MOP handles things like method dispatch or inheritance, which happen automatically as part of how the object system works. The explicit MOP typically handles the introspection/reflection features of the object system.
All object systems have implicit MOPs. Without one, they would not work. Explicit MOPs are much less common, and depending on the language can vary from restrictive (Reflection in Java or C#) to wide open (CLOS is a perfect example).
Does Ruby have one?
According to this thread on Reopening builtin classes, redefining builtin functions? Perlmonks article I think the answer is no (at least in the strictest sense of what a MOP is).
Clearly there is some wriggle room here so it might be worth posting a question in the Perl side of SO because the Class::MOP / Moose author does answer questions there.
If you look closer to the definition, youll see that Ruby does have a MOP. Is it like the one in CLOS? No, CLOS is a meta-circular MOP which is great (I'd even say genius), but it's not the one true way, take a look at Smalltalk. To implement a (let's say basic) MOP all you need is to provide functions that allow your runtime to:
Create or delete a new class
Create a new property or method
Cause a class to inherit from a different class ("change the class structure")
Generate or change the code defining the methods of a class.
And Ruby provides a way to do all that.
On a side note: The author of Class::MOP is right (IMHO) when it claims that some of the things you can do with a meta circular MOP can be hard to do in Ruby (DISCLAIMER: I have zero, zilch, nada Perl knowledge, so I'm thinking Smalltalk like MOP vs CLOS like MOP here) but most of them are very specific (I'm thinking about metaclass instantation here) and there are ways to make things work without them. I think it all depends on your point view, meta circular MOPs are cooler but more on the academic side and non meta circular MOPs are more practical and easier to implement.

Resources