Ruby doesn't have interfaces, but how tell other programmers what need to include current module in class, like instance variables, methods, constants, etc?
There's no way of formally defining what's required, it's up to you to document it clearly. The reason for this is Ruby is very dynamic by design so static tests won't work, the problems they detect might be rectified by the time the code is actually executed. Likewise, something that might seem correct could be broken later on by some other code.
C++, Java, and even Objective-C and Swift can do compile-time checking to enforce these things. Once a class is defined it cannot be undefined. Once a method is created it can't be removed. This is not the case in a Smalltalk-derived language like Ruby.
Ruby has no ability to test these things up-front since what the program actually does can change radically from the time the code is loaded and parsed, and when it's actually executed.
If you have a particularly complicated footprint you might want to write a method for testing it that can be exercised to verify that everything's working correctly. That can be called by the programmer whenever they think they're ready.
The only way to verify that your Ruby code is running correctly is to run it. No amount of static analysis will ever come close to that.
There are some existing mixins, classes, and methods in the Ruby core library that have the exact same problem, e.g. Enumerable, Comparable, Range, Hash, Array#uniq: they require certain behavior from other objects in order to work. Some examples are:
Enumerable:
The class must provide a method each, which yields successive members of the collection. If Enumerable#max, #min, or #sort is used, the objects in the collection must also implement a meaningful <=> operator […]
Comparable:
The class must define the <=> operator, which compares the receiver against another object, returning -1, 0, or +1 depending on whether the receiver is less than, equal to, or greater than the other object. If the other object is not comparable then the <=> operator should return nil.
Range:
Ranges can be constructed using any objects that can be compared using the <=> operator. Methods that treat the range as a sequence (#each and methods inherited from Enumerable) expect the begin object to implement a succ method to return the next object in sequence. The step and include? methods require the begin object to implement succ or to be numeric.
Hash:
A user-defined class may be used as a hash key if the hash and eql? methods are overridden to provide meaningful behavior.
And in order to define what "meaningful behavior" means, the documentation of Hash further links to the documentation of Object#hash and Object#eql?:
Object#hash:
[…] This function must have the property that a.eql?(b) implies a.hash == b.hash. […]
Object#eql?:
[…] The eql? method returns true if obj and other refer to the same hash key. […]
So, as you can see, your question is a quite common one, and the answer is: documentation.
This is a subjective question, so with that in mind here is my opinion.
Maybe you could create a base class that your objects inherit from.
for example:
class BaseA
def say(msg)
raise NotImplementedError
end
end
class A < BaseA
def say(msg)
puts "saying #{msg}"
end
end
Even though this isn't a real interface you can "pretend" it's one and have all the classes that need BaseA's methods and then override them with the real behavior. Then I suppose developers could just look at the base class to see what methods need to implemented.
Related
Rubocop dislikes the following; it issues Pass a binding, __FILE__ and __LINE__ to eval.:
sort_lambda = eval "->(a) { a.date }"
Yes, I know that eval is a security problem. The issue of security is out of scope for this question.
The Ruby documentation on binding says:
Objects of class Binding encapsulate the execution context at some particular place in the code and retain this context for future use. The variables, methods, value of self, and possibly an iterator block that can be accessed in this context are all retained. Binding objects can be created using Kernel#binding, and are made available to the callback of Kernel#set_trace_func and instances of TracePoint.
These binding objects can be passed as the second argument of the Kernel#eval method, establishing an environment for the evaluation.
The lambda being created does not need to access any variables in any scopes.
A quick and dirty binding to the scope where the eval is invoked from would look like this:
sort_lambda = eval "->(a) { a.date }", self.binding, __FILE__, __LINE__
Ideally, a null binding (a binding without anything defined in it, nothing from self, etc.) should be passed to this eval instead.
How could this be done?
Not exactly, but you can approximate it.
Before I go further, I know you've already said this, but I want to emphasize it for future readers of this question as well. What I'm describing below is NOT a sandbox. This will NOT protect you from malicious users. If you pass user input to eval, it can still do a lot of damage with the binding I show you below. Consult a cybersecurity expert before trying this in production.
Great, with that out of the way, let's move on. You can't really have an empty binding in Ruby. The Binding class is sort of compile-time magic. Although the class proper only exposes a way to get local variables, it also captures any constant names (including class names) that are in scope at the time, as well as the current receiver object self and all methods on self that can be invoked from the point of execution. The problem with an empty binding is that Ruby is a lot like Smalltalk sometimes. Everything exists in one big world of Platonic ideals called "objects", and no Ruby code can truly run in isolation.
In fact, trying to do so is really just putting up obstacles and awkward goalposts. Think you can block me from accessing BasicObject? If I have literally any object a in Ruby, then a.class.ancestors.last is BasicObject. Using this technique, we can get any global class by simply having an instance of that class or a subclass. Once we have classes, we have modules, and once we have modules we have Kernel, and at that point we have most of the Ruby built-in functionality.
Likewise, self always exists. You can't get rid of it. It's a fundamental part of the Ruby object system, and it exists even in situations where you don't think it does (see this question of mine from awhile back, for instance). Every method or block of code in Ruby has a receiver, so the most you can do is try to limit the receiver to be as small an object as possible. One might think you want self to be BasicObject, but amusingly there's not really a way to do that either, since you can only get a binding if Kernel is in scope, and BasicObject doesn't include Kernel. So at minimum, you're getting all of Kernel. You might be able to skimp by somehow and use some subclass of BasicObject that includes Kernel, thereby avoiding other Object methods, but that's likely to cause confusion down the road too.
All of this is to emphasize that a hypothetical null binding would really only make it slightly more complicated to get all of the global names, not impossible. And that's why it doesn't exist.
That being said, if your goal is to eliminate local variables and to try, you can get that easily by creating a binding inside of a module.
module F
module_function def get_binding
binding
end
end
sort_lambda = eval "->(a) { a.date }", F.get_binding
This binding will never have local variables, and the methods and constants it has access to are limited to those available in Kernel or at the global scope. That's about as close to "null" as you're going to get in the complex nexus of interconnected types and names we call Ruby.
While I originally left this as a comment on #Silvio Mayolo's answer, which is very well written, it seems germane to post it as an answer instead.
While most of what is contained within that answer is correct we can get slightly closer to a "Null Binding" through BasicObject inheritance:
class NullBinding < BasicObject
def get_binding
::Kernel
.instance_method(:binding)
.bind(self)
.call
end
end
This binding context has as limited a context as possible in ruby.
Using this context you will be unable to reference constants solely by name:
eval 'Class', NullBinding.new.get_binding
#=> NameError
That being said you can still reference the TOP_LEVEL scope so
eval '::Class', NullBinding.new.get_binding
#=> Class
The methods directly available in this binding context are limited only to the instance methods available to BasicObject. By way of Example:
eval "puts 'name'", NullBinding.new.get_binding
#=> NoMethodError
Again with the caveat that you can access TOP_LEVEL scope so:
eval "::Kernel.puts 'name'", NullBinding.new.get_binding
# name
#=> nil
After reading the Collections chapter in Peter Jones' book, Effective Ruby, the Set class may seem to provide an interesting alternative to Hash. Concerning the Set class, Jones relates:
It’s a lot like its mathematical cousin, a collection of unordered unique elements with operations such as union, intersection, and subset/superset testing.
My only concern is in whether the Set class may not provide direct access to actual member objects.
Presently, I'm trying to use Set (or something like Set) to implement a naive OptionSet API, such that an option in the OptionSet may be of a type Option or ValueOption, with the latter being a subclass of Option. This API may need access to the objects stored in what respective collection for each OptionSet - whether stored in a separate Hash, Array, some other container object, or stored in the OptionSet via some inherited implementation e.g with Set as a superclass.
I'd like to use Set within OptionSet, or to simply implement OptionSet as a subclass of Set. However, if Set may not provide direct access to the member objects, once stored - short of iterating across every member object in the Set, as until finding any ostensible match (e.g. once finding any Option or ValueOption in the collection, such that the "match" would have an equivalent Option.name, typically a symbol) - maybe there's a more effective alternative?
I'd provide sample code, but the implementation of OptionSet is not presently usable. In pseudocode, I'm trying to implement OptionSet#getopt(name) as to return the value of any named Option object stored in the OptionSet, or false if no such option is stored.
The #getopt method would call self.getoptObj(name), a protected method such that would need to access the named option's actual Option object in the collection. Except for that part of the implementation, otherwise Set might be directly suitable.
In any analogy to Scheme-like languages, the Ruby standard library might not provide an AssociativeList class, per se? Simply, I wonder if there's any class like Set -- i.e with set-theoretic methods as in Set -- but with the member access of Hash?
Update
I've tried to implement a MappedSet class, at least in pseudocode, such as to use an instance Hash value to store a mapping between general "Keys" and member objects. I believe that would be redundant to the international storage of Set, however. Maybe I should simply extend Hash.
If you want to create a hash like class you can use DelegateClass:
class FalsyHash < DelegateClass(Hash)
def initialize(hash)
super.tap { |result| result.default = false }
end
end
irb(main):001:0> f = FalsyHash.new(a: :b)
=> {:a=>:b}
irb(main):002:0> f[:b]
=> false
irb(main):003:0> f.is_a?(Hash)
=> false
This is basically just a class that takes an instance of the provided class and wraps it so that method calls are forwarded. Since its not actually an instance of Hash we avoid the pitfalls that happen when core methods check if we are dealing with a hash which would occur if we used a subclass of Hash.
The same thing can be acheived with Delegator, SimpleDelegator and Forwardable - DelegateClass is just a straight forward way of wrapping classes.
You can also augment specific instances of Hash by extending them with a module:
module Reversable
def reverse
transform_values { |v| v.respond_to?(:reverse) ? v.reverse : v }
end
end
# Guess what this returns for a cookie
{ foo: 'olleH', bar: nil, baz: 'dlrow' }.extend(Reversable)
.reverse
.values
.compact
.sort
.join(" ")
Currently reading a Ruby style guide and I came across an example:
def no_op; end
What is the purpose of empty body methods?
There are a number of reasons you might create an empty method:
Stub a method that you will fill in later.
Stub a method that a descendant class will override.
Ensure a class or object will #respond_to? a method without necessarily doing anything other than returning nil.
Undefine an inherited method's behavior while still allowing it to #respond_to? the message, as opposed to using undef foo on public methods and surprising callers.
There are possibly other reasons, too, but those are the ones that leapt to mind. Your mileage may vary.
There may be several reasons.
One case is when a class is expected to implement a specific interface (virtually speaking, given that in Ruby there are no interfaces), but in that specific class that method would not make sense. In this case, the method is left for consistency.
class Foo
def say
"foo"
end
end
class Bar
def say
"bar"
end
end
class Null
def say
end
end
In other cases, it is left as a temporary placeholder or reminder.
There are also cases where the method is left blank on purpose, as a hook for developers using that library. The method it is called somewhere at runtime, and developers using that library can override the blank method in order to execute some custom callback. This approach was used in the past by some Rails libraries.
Here is a code sample from the ruby pickaxe book:
Class VowelFinder
include Enumerable
def initialize(string)
#string = string
end
def each
#string.scan(/[aeiou]/] do |vowel|
yield vowel
end
end
end
vf = VowelFinder.new("the quick brown fox jumped")
vf.inject(:+) # => 'euiooue'
What I am having a hard time understanding is where the modified 'each' method comes into play? I assume inject is calling it at some point but don't understand why it's doing it, and how I could predict or emulate this behavior in my code.
Thanks!
the VowelFinder class implements the protocol that is mandatory for the Enumerable module that you can include to gain a lot of ruby iterator methods: http://apidock.com/ruby/Enumerable
The Enumerable mixin provides collection classes with several
traversal and searching methods, and with the ability to sort. The
class must provide a method each, which yields successive members of
the collection. If Enumerable#max, #min, or #sort is used, the objects
in the collection must also implement a meaningful <=> operator, as
these methods rely on an ordering between members of the collection.
The call to inject actually causes a call to each. The way inject works is by going over all the elements of the Enumerable using each, applying the passed operator to the memo and to the next value and storing the result back into memo. The result of the entire call is the value of memo in the end. You can see the documentation in here.
You are correct that inject actually calls each method and the reason this happens is because inject actually uses each method internally. In fact, a lot if the Enumerable methods use the .each method; like #map, #select, #reject.
The reason for this is that .each is the actual method which allows looping in an Enumerable Object. The other methods are just so that things get easy for us, developers, and we don't have to use .each everywhere. Imagine having to write the above code using .each. It wouldn't be tough but vf.inject(:+) is definitely easier. So is the case with collect or map.
And the best way to implement this(as is done in Ruby) without repeating code is to have the other method call #each as there is no code duplication and each of #map or #collect or #inject does not have to traverse the Enumerable Object differently.
Genrally, I avoid using #each and there are so many other methods which makes our job easier. If you want to modify your array collection, it's advisable not to money-patch the #each method (unless, of course, you want all the other methods to change as well.)
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.