Ruby Methods and Params Validation - ruby-on-rails

I have a general questions about how to treat params on a method. Let's say, we have a method that receives a number and multiplies it by 2.
def multiplier(num)
num*2
end
What happens when num is nil? Who is responsible to handle the error? The method itself or the one who calls the method? What is considered the best oop practice?

This is not related to OOP in any way, because it applies to other paradigms as well. That said, there are different schools of thought about the problem. Which one is the "best" depends on who you're talking to.
One is "defensive programming everywhere". This means each method is responsible for rigorous checks of its input.
Another is "caller is responsible for providing correct data".
Another is what I call a "security perimeter": rigorous checks only when we deal with external input, but once data is "inside of the system", it can be trusted.
And anything in between.

I agree with the other answers (#sergio-tulentsev, #Зелёный). And there is another thing to consider.
In a lot of cases it is a good practice not to expect an object of particular type, but an object which acts like a particular type. I mean, in your case, the method could expect not only a number to be passed as a parameter, but any object that could be treated like a number. That would not only make your method more powerful, but also solve the nil problem. Of course it depends on your needs.
The method version I am talking about might look like this:
def multiplier(num)
# trying to convert whatever is passed to a number
num.to_f * 2
end
In the case of nil it will return 0.0

Related

Creating and storing generic methods in ruby on rails

I'm making a method inside a Ruby on Rails app called "print" that can take any string and converts it into a png. I've been told it's not good to make class methods for base ruby classes like String or Array or Hash, etc. so "some string to print".print is probably not something I should do.
I was thinking about making a subclass of String called Print (class Print < String) and storing it in my lib/assets folder. So it would look like: Print.new("some string to print"). So my question is, am I on the right track by 1) creating a sub-class from String and 2) storing it in lib/assets?
Any guidance would be greatly appreciated!
Answers to your question will necessarily be subjective because there are always be many answers to "where should I put functionality?", according to preference, principle, habit, customs, etc. I'll list a few and describe them, maybe add some of my personal opinions, but you'll ultimately have to choose and accept the consequences.
Note: I'll commonly refer to the common degenerate case of "losing namespacing scope" or "as bad as having global methods".
Monkeypatch/Extend String
Convenient and very "OO-message-passing" style at the cost of globally affecting all String in your application. That cost can be large because doing so breaks an implicit boundary between Ruby core and your application and it also scatters a component of "your application" in an external place. The functionality will have global scope and at worst will unintentionally interact with other things it shouldn't.
Worthy mention: Ruby has a Refinements feature that allows you to do do "scoped monkeypatching".
Worthy mention 2: Ruby also lets you includes modules into existing classes, like String.class_eval { include MyCustomization } which is slightly better because it's easier to tell a customization has been made and where it was introduced: "foo".method(:custom_method).owner will reveal it. Normal Monkeypatching will make it as if the method was defined on String itself.
Utils Module
Commonly done in all programming languages, a Util module is simply a single namespace where class methods/static methods are dumped. This is always an option to avoid the global pollution, but if Util ends up getting used everywhere anyways and it gets filled to the brim with unrelated methods, then the value of namespacing is lost. Having a method in a Util module tends to signify not enough thought was put into organizing code, since without maintenance, at it's worst, it's not much better than having global methods.
Private Method
Suppose you only need it in one class -- then it's easy to just put it into one private method. What if you need it in many classes? Should you make it a private method in a base class? If the functionality is inherent to the class, something associated with the class's identity, then Yes. Used correctly, the fact that this message exists is made invisible to components outside of that class.
However, this has the same downfall as the Rails Helper module when used incorrectly. If the next added feature requires that functionality, you'll be tempted to add the new feature to the class in order to have access to it. In this way the class's scope grows over time, eventually becoming near-global in your application.
Helper Module
Many Rails devs would suggest to put almost all of these utility methods inside rails Helper modules. Helper modules are kind of in between Utils Module and Private Method options. Helpers are included and have access to private members like Private Methods, and they suggest independence like Utils Modules (but do not guarantee it). Because of these properties, they tend to end up appearing everywhere, losing namespacing, and they end up accessing each other's private members, losing independence. This means it's more powerful, but can easily become much worse than either free-standing class/static methods or private methods.
Create a Class
If all the cases above degenerate into a "global scope", what if we forcibly create a new, smaller scope by way of a new class? The new class's purpose will be only to take data in and transform it on request on the way out. This is the common wisdom of "creating many, small classes", as small classes will have smaller scopes and will be easier to handle.
Unfortunately, taking this strategy too far will result in having too many tiny components, each of which do almost nothing useful by themselves. You avoid the ball of mud, but you end up with a chunky soup where every tiny thing is connected to every other tiny thing. It's just as complicated as having global methods all interconnected with each other, and you're not much better off.
Meta-Option: Refactor
Given the options above all have the same degenerate case, you may think there's no hope and everything will always eventually become horribly global -- Not True! It's important to understand they all degenerate in different ways.
Perhaps functionality 1, 2, 3, 4... 20 as Util methods are a complete mess, but they work cohesively as functionality A.1 ~ A.20 within the single class A. Perhaps class B is a complete mess and works better broken apart into one Util method and two private methods in class C.
Your lofty goal as an engineer will be to organize your application in a configuration that avoids all these degenerate cases for every bit of functionality in the system, making the system as a whole only as complex as necessary.
My advice
I don't have full context of your domain, and you probably won't be able to communicate that easily in a SO question anyways, so I can't be certain what'll work best for you.
However, I'll point out that it's generally easier to combine things than it is to break them apart. I generally advise starting with class/static methods. Put it in Util and move it to a better namespace later (Printer?). Perhaps in the future you'll discover many of these individual methods frequently operate on the same inputs, passing the same data back and forth between them -- this may be a good candidate for a class. This is often easier than starting off with a class or inheriting other class and trying to break functionality apart, later.

Should I override Activerecord's update() method?

I'm refactoring my Rails 5.2 app in such a way that one model (OrigM) is being split into two (OrigM, NewM). Out in the codebase, there is code that does update on OrigM objects, and I want this to now result in specialized behavior in which associated OrigM and NewM objects are updated appropriately.
It seems like a straightforward way to do this is to override update in the OrigM model, but trying to do it a simpleminded way results in infinite recursion, because apparently even the class method OrigM.update(id, new_attrs) under the hood is just finding the object with id id and calling update as an instance method on it.
I have figured out a couple other ways I could perhaps make this work, although I haven't fully tested them yet: (1) Update OrigM attributes by calling write_attribute on them individually (seems like this will not let me check validations), or (2)
self.assign_attributes(new_attrs) ## resulting in "dirty" object, then
self.save!
I'm leaning toward this second solution, as it seems like it ought to be pretty close to functionally identical to what the standard update is doing.
EDIT:
I've realized that no one can really answer this unless I am asking a question, so I will now recast it as:
QUESTION: Should I, or should I not, override AR's update method (in OrigM class)?
Commenters have said: "do not do this or you will be reviled" (which honestly I was sure someone would say lol). But... is it really such a crime? Is there a "killer" reason not to do it (something you couldn't argue with)? Or is it just a vaguely encouraged best practice?
Also: "why not just define a new method if it does something different?" Well... I guess I need to say more about the models... I don't want to try to give actual code, because it's too complex. Suffice to say: most of the code still interacts with OrigM objects, and will not know about NewM. NewM was only needed architecturally because I needed to allow multiple OrigMs to share (belong_to) a single NewM to avoid duplication of data. So I would like to allow most of the rest of the code to maintain the illusion that there is still only OrigM, and be able to update it as usual. This feels like the most elegant solution to me. If I create a new OrigM#myupdate, future developers (including myself) might curse me because they tried to do a simple update and it broke things. Iow, isn't having to know that there is a special updating function just as confusing as having to know that AR's update has been overridden?

Proper technique when passing data between methods

If you have two methods in a model or controller and you want to pass a variable between methods e.g.
def foo
#param = 2
#test = 1
callee
#do something with #test
end
def callee
#test += #param
end
Is it better to use instance variables to do this or regular variables like so
def foo
param = 2
test = 1
test = callee(param, test)
#do something with test
end
def callee(param, test)
test += param
test
end
Thanks in advance!
There isn't a definite answer to this question, it depends a lot on the context - the thing you need to ask is "which approach best demonstrates the intent of the code". You should definitely have tests for the model/controller class you are talking about.
As a very rough guideline:
The first approach is commonly seen when the method is part of the class's public API and it alters the internal state of instances of the class (although it may be the sign of a code smell if you have public methods chained as in your example.) This is probably going to be seen more often in a model object.
The second approach is usually seen when the method you are calling is a private convenience method that factors out some code duplication, or a method which does very specialised operations on the parameters and returns some result (in which case it should probably be factored out into a utility class.) This may be seen in model or controller objects.
If you are aiming for maintainable OO code, then the principles of SOLID design are very good guidelines - have a look at Uncle Bob's article about them here:
http://blog.objectmentor.com/articles/2009/02/12/getting-a-solid-start
It depends on your needs. Also, prototype of the function that you are passing variables to is also important. If you want the method not to change any of the parameters without your permission, you should use your second implementation. But, if you trust the function, you can use first method. This is a big topic called as "call by reference" and "call by value". You can examine following link;
http://www.exforsys.com/tutorials/c-language/call-by-value-and-call-by-reference.html

Is it bad design to base control flow/conditionals around an object's class?

I'm currently working on a Rails project, and have found times where it's easiest to do
if object.class == Foo
...
else if object.class == Bar
...
else
...
I started doing this in views where I needed to display different objects in different ways, but have found myself using it in other places now, such as in functions that take objects as arguments. I'm not precisely sure why, but I feel like this is not good practice.
If it's not good practice, why so?
If it's totally fine, when are times that one might want to use this specifically?
Thanks!
Not sure why that works for you at all. When you need to test whether object is instance of class Foo you should use
object.is_a? Foo
But it's not a good practice in Ruby anyway. It'd much better to use polymorphism whenever it's possible. For example, if somewhere in the code you can have object of two different classes and you need to display them differently you can define display method in both classes. After that you can call object.display and object will be displayed using method defined in the corresponding class.
Advantage of that approach is that when you need to add support for the third class or a whole bunch of new classes all you'll need to do is define display method in every one of them. But nothing will change in places where you actually using this method.
It's better to express type specific behavior using subtyping.
Let the objects know how they are displays. Create a method Display() and pass all you need from outside as parameter. Let "Foo" know to display foo and "Bar" know how to display bar.
There are many articles on replacing conditionals with polymorphism.
It’s not a good idea for several reasons. One of them is duck typing – once you start explicitly checking for object class in the code, you can no longer simply pass an instance of a different class that conforms to a similar interface as the original object. This makes proxying, mocking and other common design tricks harder. (The point can be also generalized as breaking encapsulation. It can be argued that the object’s class is an implementation detail that you as a consumer should not be interested in. Broken encapsulation ≈ tight coupling ≈ pain.)
Another reason is extensibility. When you have a giant switch over the object type and want to add one more case, you have to alter the switch code. If this code is embedded in a library, for example, the library users can’t simply extend the library’s behaviour without altering the library code. Ideally all behaviour of an object should be a part of the object itself, so that you can add new behaviour just by adding more object types.
If you need to display different objects in a different way, can’t you simply make the drawing code a part of the object?

F# Instance Methods... should they return a new instance instead of altering the current object?

The problem is whether an instance method should in anyway alter the object that contains the method or should it return a new instance? I'm new to F# and the concept of full mmutability that is suggested for F#.
Just using psuedo code for now unless I need to be more specific.
First thought is just add the message to the message list on the object:
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
_messages.Add(message)
Second is to construct a new list that joins the old list and the new message. Then I would create a new instance altogther and send back.
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
newMessageList = _messages.Join(message)
return new Something(newMessageList)
Am I overthinking immutability?
In my opinion, the answer depends on your requirements. The immutable style is probably more idiomatic, and would be a sensible default. However, one nice thing about F# is that you can choose what to do based on your needs; there's nothing inherently wrong with code that uses mutation. Here are some things to consider:
Sometimes the mutable approach leads to better performance, particularly when used in a single-threaded context (but make sure to measure realistic scenarios to be sure!)
Sometimes the immutable approach lends itself better to use in multi-threaded scenarios
Sometimes you want to interface with libraries that are easier to use with imperitave code (e.g. an API taking a System.Action<_>).
Are you working on a team? If so, are they experienced C# developers? Experienced F# developers? What kind of code would they find easiest to read (perhaps the mutable style)? What kind of code will you find easiest to maintain (probably the immutable style)?
Are you just doing this as an exercise? Then practicing the immutable style may be worthwhile.
Stepping back even further, there are a few other points to consider:
Do you really even need an instance method? Often, using a let-bound function in a module is more idiomatic.
Do you really even need a new nominal type for what you're doing? If it's just a thin wrapper around a list, you might consider just using lists directly.
As you are doing "class based" programming which is one of the way (rather unfortunate) to do object oriented programming, you would be doing in place state modification rather than returning a new state (as that's what would be expected when you are doing OO).
In case you really want to go towards immutability then I would suggest you need to use more FP concepts like Modules, Functions (not methods which have you have in class based programming), recursive data types etc.
My answer is way too general and the appropriate answer lies in the fact that how this class of your will fit in the big picture of your application design.

Resources