Is it considered a good design to allow a private method in class A in ruby to call a public method in class B,
I guess a better approach would be to call another public method in class A which would call the public method in class B.
Consider a situation where a user needs to act (private method) on a resource but can't do so without examining some constraint (through a public method) of the resource.
I don't know what exact function you want, but it's no problem to allow a private method in class A in ruby to call a public method in class B like the code :
class A
private
def test_a
B.new.test_b
end
end
class B
def test_b
puts 'test_b'
end
end
A.new.send(:test_a) #=>test_b
Is it considered a good design to allow a private method in class A in
ruby to call a public method in class B
It doesn't matter whether you're calling the external class from a public or private method, as private methods are an implementation detail. What matters is whether it makes sense for the given class to know about that external classes' method.
Consider a situation where a user needs to act (private method) on a resource but can't do so without examining some constraint (through a public method) of the resource.
Taking into account your comment:
if the user wants to enter the house he needs to check if the house is safe
One possible implementation would be:
class User
def enter(house)
if house.safe?
house.users << user
end
end
end
This requires the User class to know a few things about the House class:
it implements a safety validation via #safe?
it stores entered users in a users array
This means User knows quite a bit about House. If House changes the implementation of the above two items, User needs to change too.
An alternate design would be to invert the owner of the functionality:
def House
def entry_for(user)
if safe?
users << user
end
end
end
Now, the coupling between these two classes has been reduced. As the owner of the safe? constraint, House controls whether users are allowed in while User remains blissfully ignorant of the implementation of House.
Depending on the domain in question, the assertion of safety might belong to a class other than House or User, eg. Guard. In this case, you might end up with something like:
class Guard
def facilitate_entry(user, house)
house.enter_by(user) if safe?(house)
end
private
def safe?(house)
end
end
I dont think that would be a good approach, to create a public methods to access other class's public methods. You would get overwhelmed with too many public methods in your class.
As Ruby is pure object oriented and everything is object there. If you go with that approach in mind, you will ended up with unnecessary methods. Even if you are doing simple stuff in your private method. Let say you are trying to iterating an array with each method. Would you consider creating a public methods to first to access public method each of class Array ? Answer is simply no.
Also ruby is an expressive and productive language. You could do more is less code in ruby.
Related
I have two questions regarding Ruby core OOP concepts.
I understand the differences between explicit call (i.e. with self) and implicit call (i.e. without initialized class object or self in an instance method) of a method. When we have explicit receivers that do very neat and clear job of receiving a method with self (since it refers to the current object) rather than implicit ones (which I believe is very uncertain in situations like when to use method or variable of same name initialized), then why do we still have to call methods implicitly? Is it just a preference or is it necessary because of proper usage of private and public methods?.
In general, OOP private methods are bound within the class itself and cannot be accessed in subclasses or outside. However, those methods that need to be private but also need to be accessed in subclasses then protected methods are used over there. But in Ruby, both private and
protected methods are accessed in inherited classes, and the only difference is that private methods can only be called implicitly and protected methods can either be called implicitly or explicitly. I don't understand the philosophy over here that only because of implicit calling functionality in ruby, general definitions of private methods differ?
I think you have a slight misunderstanding of the purpose of protected methods. Protected methods can be called from methods of another instance of the same class.
class Person
def initialize(name, age)
#name = name
#age = age
end
def older_than?(other_person)
age > other_person.age
end
protected
def age
#age
end
end
mother = Person.new('Carole', 34)
father = Person.new('George', 37)
If you try...
mother.age
=>NoMethodError: protected method `age' called for #<Person:0x0000000327daa0 #name="Carole", #age=34>
So you cannot, externally, call the #age method.
But you can do...
father.older_than?(mother)
=> true
So the father object was able to call the mother object #age method, because he is an object of the same class Person.
In the discussion below, recall that the only way to call an instance method with an implicit receiver (self) is to do so from within an instance method of the same class.
The question is why Ruby was designed to permit most1 instance methods to be called with an implicit receiver.
One would probably have to ask Matz to get an authoritative answer, but my guess is that it traces back to the way private instance methods were implemented. Requiring that they be called with an implicit receiver was seen (I'm guessing) as a simple way to prevent them from being called from anywhere other than from within an instance method of the same class.
But if private methods must be called with an implicit receiver, in the interest of consistency wouldn't it have made sense to permit (nearly all) public and protected instance methods to be called with an implicit receiver?
Some Rubiests see the use of the explicit receiver self as redundant, and therefore use an implicit receiver (except where self. is required). Others see the use of implicit receivers as a potential source of confusion, so use self., knowing (or possibly not knowing), that is optional. So far as I know, all core Ruby methods implemented in Ruby use implicit receivers. Those in the first camp might argue that using self. redundantly is akin to saying "Meet me at the blue wall that is colored blue".
1 There are a handful of cases where the explicit receiver self is required to avoid ambiguity. The two most common are when invoking the method class (considering class is also a keyword) and invoking a setter, which Ruby might otherwise confuse with the assignment of a value to a newly-created local variable. Another example is that we cannot write Array methods def a; [1]; end nor def a; [](1); end. Again, an explicit receiver is needed: self[1] or self.[](1).
I made a class User (which is an instance of Class), and made it inherit from class Person. What makes this considered not to be multiple inheritance? Doesn't it inherit instance methods like new from Class and any methods that Person offers?
In other words, how is this not multiple inheritance:
class User < class Person
some methods here...
end
when User already inherits all of Class's methods? Isn't the following what is going on under the hood?
class User < class Person and class Class
end
If you open irb you can check it yourself. Type User.superclass, you will see that User has only one superclass, which is Person. User will inherit the methods from Object because Person's superclass is Object
It is not "multiple inheritance" in usual way, but a simple chain of inheritance.
Ancestors cannot have own constructors unless you call them explicitly from initialize, and in complex hierarchies this can be very painful.
The main point is that there's only one instance object, that is shared and methods are mixed into it.
In ruby class hierarchy is always a tree. Even mixins, that may look like a multiple inheritance - internally are implemented as inheritance chain.
True multiple inheritance can be hard, for example, in C++:
class A {}
class B: public A{}
class C: public A{}
class D: public B, public C{}
How many instances of A should be inside D? (the "diamond problem")
Ruby avoids it by simply not having the cause.
I'm building a system that uses a lot of small classes to do data processing (each class does a different processing step, nice & SRP like). I initialize each class with some parameters then call an execute() method on the class, which then uses other private methods to do some of the data calculations.
My question is: if I'm not accessing any of the parameters outside of the class, should I just use the instance variables in the private methods? Or define an attr_reader?
For example, here's a bit of contrived code that I whipped up:
class Car
attr_reader :make
def initialize(make, model)
#make = make
#model = model
end
def execute
apply_paint
rotate_tires
end
private
def apply_paint
if make == "Toyota"
Painter.paint(self, "red")
else
Painter.paint(self, "green")
end
end
def rotate_tires
if #model == "Sequoia"
set_tire_size(:large)
else
set_tire_size(:normal)
end
end
end
So which is better? How I handled "make" or how I handled "model"?
If I know that I'm not using either of those variables outside of this class at all, should I just stick with instance variables? Or is it nicer to use the attr_reader because then I could convert them into actual methods without changing the rest of the code... i.e. since apply_paint uses make instead of #make, I could change make to be a local method if need be and not change the apply_paint method.
I keep waffling back-n-forth and can't figure out which is better. Maybe this is just a preference thing, but I wanted to see what thoughts others had on this issue.
Use attr_ methods. You can (and probably should) make them private if you're not accessing them outside of the class. Why use them? You improve readability by stating your intentions towards how it should be used. An attr_reader should be interpreted as "this variable should only be read".
Normally I expect that once an object is constructed, it should be ready for use, period. No two step construction. If you need calling two constructors for using an object something is very wrong... right?
class Contact
attr_accessor :auth_token
def initialize(contact_hash)
...
end
def edit(...)
auth_token.can! :read, self
end
end
token = AuthorizationToken.new(session)
contact = SomeService.get_contact(...)
contact.edit(...)
# raise error because auth_token is not set
contact.auth_token = token
contact.edit(...)
The code above represents my current dilemma: I want SomeService to give me Contact objects, but I do not want that service to be concerned about an existing session, or authorization at all.
My current approach is adding this extra class:
class QueryService
def initialize(session)
token = AuthorizationToken(session)
end
def get_contact
contact = SomeService.get_contact(...)
contact.token = token
end
end
contact = QueryService.new(session).get_contact(...)
contact.edit(...)
This solution gives me the most freedom to use authorization concerns inside the core domain object Contact, implement them in an external class AuthorizationToken and implement services that are not concerned about the current user session SomeService.
However the two step construction is killing me. It feels strange: An object that is not fully initialized for some operations???
This is not a plain case of dependency injection, but more exactly a context injection. So most of the articles about avoiding DI in Ruby do not really solve my problem. I am wondering if there is a more Ruby way to solve this, or this is just as clean as it can get.
Looks like your Contact class serves two purposes - storing contact data and doing some authorized requests - so yes it does violate the Single Responsibility Principle.
This could be fixed by splitting the Contact class into two - one maybe a Struct or even a plain hash to store the data, and the second that has does the requests.
And I think the most Ruby way to do it would be to return hashes from SomeService and instantiate with Contact.new(data, auth_token) later on.
I have a two part question:
Part 1
I have a module that has a public class method which depends on a few private helper methods in the module. What is the best way to test these private helper methods? They contain complex logic that needs to be tested, but they should not be exposed to be called as they alone provide nothing useful.
I read on this stackoverflow post that the convention is to do:
module GTranslate
class Translator
def perform( text ); 'hola munda'; end
end
def self.translate( text )
t = Translator.new
t.perform( text )
end
end
and then write tests on the public methods of class GTranslate::Translator. However, I do not want this class to be able to instantiate or have the methods on them called.
Part 2
Seeing that the public method on a module is defined as self.someMethodName, does this mean the helper methods have to be defined as self.helperName?
There will be no instance of a module (if you can even create instances of modules (I'm new to Ruby)) so I can't use the send method defined on an instance to invoke the method from my tests?
Any ideas?
There is some bit of debate about testing private methods as you will see in other answers. Before you test them you should consider whether it is the best choice. David Brady has a great podcall with Robert C. (Uncle Bob) Martin where they discuss this issue and some of the possible solutions including testing through the public interface, and refactoring into a separate class.
That being said, this is Ruby. If you want to test private methods use instance_eval (or class_eval for class methods) to run your test in the context of the module.
edit: After some quick IRB work modules take a little more work
Given:
module Foo
class << self
private
def bar
...
end
end
end
To test Foo.bar put in your test file:
Module Foo
class << self
puiblic :bar
end
end
For the duration of your tests bar will be public and visible.
end edit
See also:
Yes You Should Test Private Methods (Sometimes)
Test Everything, But Not Private Methods
MORE Testing Private Method
I would say you have three options.
Find a way to test the functionality using the class's public methods. All the class functionality should generally be exposed by its public methods. If you can't test a class just by using its public methods, this may indicate a deeper problem with the design.
If option 1 doesn't work (and indeed sometimes it doesn't), refactor the private functionality out to a separate class, in which these methods are public. This seems to be what you're suggesting, and I don't see a problem with that. Testing is an integral part of the system you're building and should be treated as such. Making functionality public "just for testing" is completely valid in my opinion.
Make the functions public and test them. This is technically easiest but is less clean than option 2.
There are two cases:
The private method gets called by a public method, or by a private method that gets called by a public method, or by a private method that gets called by a private method that gets called by a public method, or … (you get the idea). In that case, you don't need to test the private method, because it is already tested through the public method.
The private method never gets called by a public method. In that case, you don't need to test it either, you can simply delete it because it never gets called.
So, in both cases you simply don't need to test it in the first place.
(Note that it's a little bit more complicated than that, since the private method might be called via reflection or other means. But the gist is: either someone somewhere calls the private method, in which case it is tested through that someone, or noone calls the private method, in which case it is dead code.)
If I may make a small advertisement for Test-Driven Development: in TDD, it is actually impossible for untested private methods to exist. The only way for a private method to be introduced into the system, is by extraction from an already tested public method. (Actually, in TDD, it is impossible for any untested code to exist, so the statement that it is impossible for untested private methods to exist is trivially true.)
In general, private methods usually are created by extracting them from a public method that has become too big or too complex. The nice thing about this is that the Extract Method Refactoring has a very convenient property: like all other Refactorings, it doesn't change the externally observable behavior, but unlike many other Refactorings, which entail rather significant changes to the internal logic (e.g. the Null Object Refactoring or the Replace Conditional With Polymorphism Refactoring), it does not change the internal logic, either. It just shuffles code around. (In fact, with a good optimizing compiler like the one in Rubinius, IronRuby or JRuby, the calls to the private methods will probably be inlined, so that the code that gets actually executed is 100% the same both before and after extracting the methods.)
So, if your code was tested before you moved into a private method, then it is guaranteed to still be tested after you move it.