Reputation: 24875
I know it is a good practice to call public_send
instead of send
on objects so as not to unintentionally call a private method. However, if I know that the methods I will be calling are public for sure, can I use send? I have written this code:
[:name, :artist, :album,].each do |attribute|
define_method "#{attribute}s" do
@songs.map { |song| song.public_send(attribute) }.uniq
end
end
Would it be considered bad practice if I replace public_send
with send
here?
Upvotes: 4
Views: 3160
Reputation: 131112
Always use public_send
where possible and avoid send
it reduces your surface area and is overall a better practice.
String.new.public_send("sleep") # error
String.new.send("sleep") # hangs
In the example above replacing public_send
with send
is fine, but what if stuff is refactored? Better establish a practice where you expose the least amount of long term risk.
Upvotes: 5
Reputation: 9394
TLDR;
Calling send is fine, it's inside your class.
Full Explanation
Alex, Here is what I have always thought about this tactic. I believe that this is well inline with the community.
The Ruby Docs say this about send:
Invokes the method identified by symbol, passing it any arguments specified. You can use
__send__
if the name send clashes with an existing method in obj.
This is a public method accessible to anyone in the world. That means anyone using your code can call private functions whenever they want!
Thus... you shouldn't really think in terms of public and private functions as you would in other languages. I would argue you change your definitions a little bit.
Public: Well-tested, robust, error-checked functions which are recommended for use by the world.
Private: Helper functions which may accept invalid input and break things.
I don't have some big rationale for this, just an overall impression about how these concepts work in Ruby.
For your specific problem its important to remember that you are the one coding this up, and I assume that your code is within a class you created. In that case, I use send
all the time! It's shorted than public_send
and I know exactly what I'm calling!
You will want to document it well enough so that anyone coming behind you will know what to be careful of.
Upvotes: 3