Ruby returning statement - ruby

I am trying to return a UserStubPresenter (a nested JSON presenter) corresponding to the user who received the email, assuming they are still present in the system. If they are no longer present, it should just be nil.
And this is what I have so far for ruby. Please explain this syntax and help me with the return statement in details.
return UserStubPresenter.new #object.recipient if #options[:shallow].to_bool

There are two important pieces to understand. First, Ruby reads this line like this:
return(UserStubPresenter.new(#object.recipient)) if #options[:shallow].to_bool
And it evaluates the if condition first. That means – as zeitnot already wrote – if #options[:shallow].to_bool is truthy then UserStubPresenter.new(#object.recipient) is evaluated and returned.
Seconds, if you don’t return explicitly, then Ruby will return the return value of the last evaluated statement. Your example is a shorter version of
if #options[:shallow].to_bool
return UserStubPresenter.new #object.recipient
else
end
The last expression is the empty else path, therefore, your that line would return nil – no explicit return nil needed.
And assuming that that line is the last line of a method then you do not need the return at all.

Related

Assign a value to a variable on RETURN PL/SQPL

Is there a way to achieve this in PL/SQL oracle ?
RETURN (return_status:=1);
It gives a compilation error when I try to do this. If this is not possible please suggest a better alternative instead of doing
return_status := 1;
RETURN (return_status);
When we execute a RETURN the procedure terminates at that point and control flow passes to the calling program. So there would be no value in this construct …
RETURN (return_status:=1);
… because nothing in the program unit could act on return_status after the RETURN.
this is a function and return_status is an OUT param
That's the root of your problem: poor design. Either return a value or have it as an OUT parameter but not both. The accepted practice in PL/SQL is that a function returns a value and has no OUT parameters. Only procedures (which don't have RETURN) have OUT parameters.
So you choices are:
return 1 and don't have an OUT parameter
set OUT parameter = 1 and return something else
make it a procedure instead
I dont understand what the problem is?
If you want to return the value return_status then the second option is just fine(if you are really doing a hardcoded assignment you could just return 1.
And I thought maybe you actually have an external variable return_status you are trying to change the value of by calling this function. In which case, use a procedure and have return_status be an IN OUT variable(maybe even just OUT).
AFAIK, you cannot assign value in the Oracle FUNCTIONS RETURN Statement.
From Oracle Docs, the syntax should be
RETURN [[(] expression [)]];
For expression refer Expressions
Only solution i can think of based on your requirement(1 condition instead of 2) is using case expression. Something like below (if you have any condition)
RETURN
CASE when return_status is not null
THEN 1
Functions with OUT parameters are permitted but smell wrong.

Does + in front of a variable in ruby ever do anything?

foo = 1
p +foo
This example code prints 1 just like if the + was not there. I know - in front of a variable gets the opposite of what the variable was (-29 becomes 29) but is there any case where a variable with a + in front of it ever does anything or can I safely remove it every time I see it? To clarify this a bit I am asking no specifically about numbers assigned to variables but any datatype in ruby.
+ is both a unary operator (one argument) and a binary operator (two arguments). It is defined on the Numeric class. Unary operators are defined using # suffix to differentiate from the binary operator.
Unary Plus—Returns the receiver.
This is the source for the method:
num_uplus(VALUE num)
{
return num;
}
So to answer your question,
Does + in front of a variable in ruby ever do anything?
NO, for Numeric values.
I just looked it up for strings and yes it does do something for frozen strings.
If the string is frozen, then return duplicated mutable string.
If the string is not frozen, then return the string itself.
static VALUE
str_uplus(VALUE str)
{
if (OBJ_FROZEN(str)) {
return rb_str_dup(str);
}
else {
return str;
}
}
is there any case where a variable with a + in front of it ever does anything
Yes. Every time. It calls the +# method.
or can I safely remove it every time I see it?
No, you can't. It will change the semantics of your code: before, it will call the +# method, after, it won't.
Whether or not that changes the outcome of your program, depends on what that method is doing. The default implementation for Numeric#+# simply returns self, but of course someone could have monkey-patched it to do something different.
Also, String#+# does something more interesting: if self is a frozen string, it will return an unfrozen, mutable copy; if self is already mutable, it returns self.
Other objects in the core library don't have a +# method, so they will usually raise a NoMethodError. If you remove the call, they won't; that is also a behavioral change.

Using "? return :"

Below is part of a Ruby function that checks for a specific directory and creates it if it does not already exist:
if Dir.exists?(dir_name) == false
Dir.mkdir(dir_name)
end
I understand that there is a shorter way of doing the exact same thing:
Dir.exists?(dir_name) ? return : Dir.mkdir(dir_name)
However, I can't quite make sense of this. The important part of the second command is ? return :. The first part of the command has the parameter to check, and the last part has the action to take, but I can't make sense of ? return :. If I wanted the action in the last part of the command to execute if and only if dir_name did already exist, what would I use instead of ? return :?
You should use
Dir.mkdir(dir_name) unless Dir.exists?(dir_name)
unless <statement> is the same as if !<statement>. Remember never to make a statement that compares a boolean value to another boolean.
For example, increasing readability of your first statement
if Dir.exists?(dir_name) == false
if !Dir.exists?(dir_name)
unless Dir.exists?(dir_name)
The line Dir.exists?(dir_name) ? return : Dir.mkdir(dir_name) uses the ternary operator.
return immediately exits the function, usually returning a value like return "some value" but you can also just call return to exit the function and return nil.
Long story short the ternary version breaks the function if the dir exists, so nothing after that in the function would happen. So the equivalent is actually
Dir.exists?(dir_name) ? nil : Dir.mkdir(dir_name)
That is another way of writing an if-else.
Condition ? IfTrue : IfFalse
So,
Dir.exists?(dir_name) ? return : Dir.mkdir(dir_name)
Is the same as:
if Dir.exists?(dir_name)
return
else
Dir.mkdir(dir_name)
end

Go code doesn't compile without an unreachable return statement

Here is the program to find the factorial of a number in Go:
func factorial(x uint) uint {
if x == 0 {
return 1
}
return x * (factorial(x - 1))
}
The output for this function when called on input 5 is 120. However, if I add an else statement I get an error.
func factorial(x uint) uint {
if x == 0 {
return 1
} else {
return x * (factorial(x - 1))
}
}
Error : function ends without a return statement
I added a return at the end :
func factorial(x uint) uint {
if x == 0 {
return 1
} else {
return x * (factorial(x - 1))
}
fmt.Println("this never executes")
return 1
}
and I get back the expected output of 120.
Why would the second case cause an error? Why in the third case even though the function never reaches the last return 1, it computes the correct output?
This is a well known problem of the compiler.
There is even an issue logged : http://code.google.com/p/go/issues/detail?id=65
In the words of one of the authors of the Go language:
The compilers require either a return or a panic to be lexically last
in a function with a result. This rule is easier than requiring full
flow control analysis to determine whether a function reaches the end
without returning (which is very hard in general), and simpler than
rules to enumerate easy cases such as this one. Also, being purely
lexical, the error cannot arise spontaneously due to changes in values
such as constants used in control structures inside the function.
-rob
From another comment in golang-nuts, we can infer it's not going to be "fixed" soon :
It's not a bug, it's a deliberate design decision.
-rob
Note that other languages like Java have rules allowing this else.
March 2013 EDIT - It just got changed in Go1.1 :
Before Go 1.1, a function that returned a value needed an explicit
"return" or call to panic at the end of the function; this was a
simple way to make the programmer be explicit about the meaning of the
function. But there are many cases where a final "return" is clearly
unnecessary, such as a function with only an infinite "for" loop.
In Go 1.1, the rule about final "return" statements is more
permissive. It introduces the concept of a terminating statement, a
statement that is guaranteed to be the last one a function executes.
Examples include "for" loops with no condition and "if-else"
statements in which each half ends in a "return". If the final
statement of a function can be shown syntactically to be a terminating
statement, no final "return" statement is needed.
Note that the rule is purely syntactic: it pays no attention to the
values in the code and therefore requires no complex analysis.
Updating: The change is backward-compatible, but existing code with
superfluous "return" statements and calls to panic may be simplified
manually. Such code can be identified by go vet.
And the issue I mentioned is now closed with status "Fixed".

Does the || operator evaluate the second argument even if the first argument is true?

I'm trying to evaluate the expression (a=10) || (rr=20) while the rr variable is not defined
so typing rr in the ruby console before evaluating the previous expression returns
rr
NameError: undefined local variable or method `rr' for main:Object
from (irb):1
from :0
When I write the expression (a=10) || (rr=20) it returns 10, and when I write rr afterwards it says nil
(a=10) || (rr=20)
rr # => nil
so, why is this happening? Shouldn't rr be defined only if the second argument of the || operator is evaluated, which should be never based on the documentation?
This happens because the ruby interpreter defines a variable when it sees an assignment to it (but before it executes the actual line of code). You can read more about it in this answer.
Boolean OR (||) expression will evaluate to the value of left hand expression if it is not nil and not false, else || will evaluate to the value of right hand expression.
In your example the ruby interpreter sees an assignment to a and rr (but it doesn't execute this line yet), and initializes (defines, creates) a and rr with nil. Then it executes the || expression. In this || expression, a is assigned to 10 and 10 is returned. r=20 is not evaluated, and rr is not changed (it is still nil). This is why in the next line rr is nil.
As #DOC said, && and || are known as short circuited conditional operators.
In case of ||, if the left part of || expression returns true, the right part won't be executed. That means the right part will be executed only if the left part of || expression returns false.
In case of &&, right part of the&&expression will be executed only if left part of && returns true.
In the given scenario (a=10) || (rr=20), rr=20 won't be executed since the ruby expression a=10 returns true. Note that in ruby assignment expression returns true except nil and false.
I think variable definement happens at the parsing stage, not the execution moment. So when it evaluates the line, it parses the whole thing and the variable is defined, but unassigned.
When the parser discovers a variable it is automatically valid within the context it's defined in. Evaluating rr on its own is not valid. Evaluating rr=20 is sufficient to cause a definition even if the value assignment never occurs.
This is a quirk of how Ruby tries to discern between variables and method calls. It's imperfect but usually works out for the best.

Resources