0

Ruby doesn't have interfaces, but how tell other programmers what need to include current module in class, like instance variables, methods, constants, etc?

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Yeah, friday evening. I need some rest :)
@SergioTulentsev It's like when ordinary words start to look unfamiliar and confusing. Is it really spelled "weird"? That doesn't seem right.
I immediately thought that you wanted to write "does change", then decided to change it to "can change", but forgot to remove the "does". Happens to me sometimes. Even though I now know this sentence is syntactically fine, I can't unsee that. :)
1

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.