Shortcut to avoid checking presence of a hash value twice - ruby

I have a hash that may or may not contain a value for a certain key. If it does, I want to transform that value and assign the transformed value to an attribute. If not, I want to set the attribute to nil (or leave it undefined, which in this case has the same effect).
Is there a more concise / idiomatic alternative to the following code?
#my_attr = some_xform(a_hash[:a_key]) if a_hash[:a_key]
I feel like there should be DRY alternative that doesn't require mentioning :a_key twice (i.e., not has_key?[:a_key] either).
(Note that some_xform() is a library method that blows up if it gets nil, which in most cases is the desired behavior -- I don't want to monkey-patch it to silently return nil for nil just to handle this case. Nor is there any default value I can pass that will cause it to return nil.)

Would that work?
#my_attr = if (v = a_hash[:a_key]) then some_xform(v) end

Since you apparently don't need to treat false specially
#my_attr = (v = a_hash[:a_key]) && some_xform(v)

You could do this (although not consider best practice by some):
#my_attr = some_xform(a_hash[:a_key]) rescue nil

Use the short circuting logic of &&:
#my_attr = a_hash[:a_key] && some_xform(a_hash[:a_key])
If a_hash[:a_key] is nil, then && will not evaulate the right hand side, and just return nil.

Related

Implicitly lazy gather/take not considered a "lazy" object

The documentation for gather/take mentions
Binding to a scalar or sigilless container will also force laziness.
However,
my \result = gather { for 1..3 { take $_² } };
say result.is-lazy # OUTPUT: «False␤»
Same happens if you use a scalar, and binding using := Is there some way to create implicitly lazy gather/take statements?
Update: It's actually lazy, only it does not respond to the is-lazy method in the expected way:
my $result := gather { for 1..3 { say "Hey"; take $_² } };
say $result[0] # OUTPUT: «Hey␤1␤»
So the question is "What are the conditions for is-lazy to consider things actually lazy?"
I think the problem is really that you cannot actually tell what's going on inside a gather block. So that's why that Seq object tells you it is not lazy.
Perhaps it's more a matter of documentation: if is-lazy returns True, then you can be sure that the Seq (well, in fact its underlying Iterator) is not going to end by itself. If is-lazy returns False, it basically means that we cannot be sure.
One could argue that in that case is-lazy should return the Bool type object, which will also be interpreted as being false (as all type objects are considered to be False in boolean context). But that would at least give some indication that it is really undecided / undecidable.

Use the result of checked method inside conditional statement

I'm trying to implement and Authorization module, because currently the authorization logic for a certain resource is separated on two or three different places and even though I'm not sure this is the best approach, at least I think it will provide some encapsulation.
Since I'm checking for several different things
Does the user have the right role
Is the resources in the right state to process the required action
Do the user has the right to perform the required action on this particular resource
So as you can see, there are several checks, I'm not pretending to be completely correct here, but this is pretty close to the real case, so I've decided to use something like a Result Object even though it's actually not an object but a struct and I'm not using Gem but pretty simple custom implementation.
So part of my Authorization module is this:
module Authorization
Result = Struct.new(:successfull?, :error)
extend self
def read(user, resource, message: 'Permission denied')
can_read =
[
condition1,
condition2,
condition3
]
return Result.new(can_read.any?, can_read.any? ? nil : message))
end
However within this Authorization module I have a lot of methods and some of them check read internally like so:
def assign(user, resource, message: 'Permission denied')
return read(user, resource) unless read(user, resource).successfull?
Result.new(true, nil)
end
So my main question is how to avoid this double call to read(user, resource). I guess one option would be to just call it before the check like:
result = read(user, resource)
return result unless result.successfull?
However I'm pretty new to Ruby and I suspect that maybe there is more ruby-like way to do this. Just to inline it somehow by assigning the result from read inside the condition check...However this is just wild guess.
And one more question, that came up while I was writing this. Currently if I want to send nil for message when the authorization passes I'm doing this:
return Result.new(can_read.any?, can_read.any? ? nil : message))
Because message unless can_read.any? is throwing and error even though I thought it would default to nil. So again, is there some more ruby-like way to do this?
First part can be written with Object#yield_self:
def assign(user, resource, message: 'Permission denied')
read(user, resource).yield_self do |res|
res.successful? ? Result.new(true, nil) : res
end
end
successfull? -> successful? for English reasons. I am not convinced this is more readable than using a local variable though. Alternatively:
(res = read(user, resource)).successful? ? Result.new(true, nil) : res
As for your second question, you'll need more parentheses
Result.new(can_read.any?, (message if can_read.none?))
the return is not needed.
I would also advise you to slow down with all the unlesses, try to swap your conditions to if whenever possible -- I find it quite useful to make Result a class and define a failed? method for it. Actually, I'd consider this:
class Result
def initialize(error)
#error = error
end
def successful?
#error.nil?
end
def failed?
!successful?
end
end
That depends on how complicated your Result gets, but for the use case shown, it would be a little cleaner imho.

Swift Wrap and Unwrap

I'm a little confused about Swift Wrap and Unwrap! So lets say this is my code:
var name:String? = "FirstName"
print(name)
Does the print function automatically unwrap the name which is optional? so I do not need to say
print(name!) in order to unwrap the name?
I guess what I am trying to understand is these two are equivalent for unwraping an optional variable?
print("name") is just like saying print ("name"!)
The other question I have is about nil.
is saying var name:String? = "FirstName" equivalent to saying var name:String? = nil . So does assigning a nil value wraps a variable?
When something can be nil it can be two things, it can be Some (the value of the given type) or it can be nil.
declaring something like this:
var name: String?
Means that the name variable can be nil, if you assigned a value to it you need to unwrap it to use it.
name = "FirstName"
Now the name variable has been defined, however you still need to ensure it's not nil in some cases, in other cases however (such as when the string doesn't need to be not nil) optional chaining is used.
Optional chaining allows the continuous evaluation of nil or some throughout a statement as long as it's not required to be not nil. If that is the case then you will need to unwrap it:
let someThingRequiresAString = NeedAStringInitializer(string: name!)
In the above statement if name is nil the program will crash, there are several approaches to dealing with things like this, here's a quick example:
if name != nil {
let someThingRequiresAString = NeedAStringInitializers(string: name!)
}
Here you know you can do this b/c name has been evaluated to not be nil. You can also use a nil coalescing operator, or a guard statement. Here's a quick example of nil coalescence in Swift:
let someThingRequiresAString = NeedAStringInit(string: name ?? "New Name")
The optional paradigm is quite powerful and expressive.

Swift Optionals vs. Ruby ||=

I'm making the transition from learning Ruby to Swift and trying to make any useful associations in order to get a better understanding of similar concepts from both programming languages. I noticed in Swift there are optionals which either have or don't have a value assigned to variables.
var optinalString: String? = "This is optional"
In Ruby we have ||= which from what I understand does something very similar where if the user doesn't assign a value to this variable, then it will use the predefined one that's already been set.
optionalString ||= "This is optional"
Am I on the right track with this assumption? Overall what makes these concepts similar/different?
These two concepts are not equivalent.
In your Swift example, you're creating a variable of type String? and assigning it the value of a string literal. In the Ruby example, you're assigning a string literal to your optionalString variable if optionalString is undefined, nil, or evaluates false (more info).
In Swift, when you create a variable of optional type, all you're doing is specifying that the variable is allowed to be nil, so a closer representation of your Ruby example might look like this:
var optionalString: String?
optionalString = optionalString ?? "This is optional"
Which uses Swift's nil coalescing operator and is equivalent to the following usage of the ternary conditional operator, where optionalString is assigned the unwrapped value of optionalString if it isn't nil, or a fallback value of "This is optional" if it isn't.
optionalString = optionalString != nil ? optionalString! : "This is optional"
Note that by doing this, your variable will still have an optional type and need to be unwrapped to be used, and since you're fallback value is a string literal that won't ever be nil, you can confidently forcibly unwrap the optional with the ! operator.
But even though this can be used to set a variable with a fallback value, it still isn't entirely the same as your Ruby example since all it's doing is checking the nilness of the variable, and not whether it evaluates false or is undefined.
In Swift, you can't test the falseness of variables by sticking them into conditions unless they are instances of a type that conforms to the BooleanType protocol. This means that if you wanted to achieve something similar with a type that supports a falseness check, you could implement something like this:
var optionalBool: Bool? = false
optionalBool = optionalBool != nil ? (!optionalBool! ? true : optionalBool!) : true
Which will assign a fallback value of true to the optionalBool variable if the variable is either nil or evaluates to false. (optionalBool will still need to be unwrapped for most uses)
But this still leaves a difference with undefined variables, and as far as I know, there isn't any way to achieve the equivalence to Ruby's ||= in this regard in Swift without inlining the nilness checks in the instantiation of a variable based on a fallback value and the value of some other variable.
var optionalString: String?
var nonOptionalString = optionalString ?? "This is not optional"
Note, there's no point in nonOptionalString being optional here, since it will always have a value.

Which syntax is better for return value?

I've been doing a massive code review and one pattern I notice all over the place is this:
public bool MethodName()
{
bool returnValue = false;
if (expression)
{
// do something
returnValue = MethodCall();
}
else
{
// do something else
returnValue = Expression;
}
return returnValue;
}
This is not how I would have done this I would have just returned the value when I knew what it was. which of these two patterns is more correct?
I stress that the logic always seems to be structured such that the return value is assigned in one plave only and no code is executed after it's assigned.
A lot of people recommend having only one exit point from your methods. The pattern you describe above follows that recommendation.
The main gist of that recommendation is that if ou have to cleanup some memory or state before returning from the method, it's better to have that code in one place only. having multiple exit points leads to either duplication of cleanup code or potential problems due to missing cleanup code at one or more of the exit points.
Of course, if your method is couple of lines long, or doesn't need any cleanup, you could have multiple returns.
I would have used ternary, to reduce control structures...
return expression ? MethodCall() : Expression;
I suspect I will be in the minority but I like the style presented in the example. It is easy to add a log statement and set a breakpoint, IMO. Plus, when used in a consistent way, it seems easier to "pattern match" than having multiple returns.
I'm not sure there is a "correct" answer on this, however.
Some learning institutes and books advocate the single return practice.
Whether it's better or not is subjective.
That looks like a part of a bad OOP design. Perhaps it should be refactored on the higher level than inside of a single method.
Otherwise, I prefer using a ternary operator, like this:
return expression ? MethodCall() : Expression;
It is shorter and more readable.
Return from a method right away in any of these situations:
You've found a boundary condition and need to return a unique or sentinel value: if (node.next = null) return NO_VALUE_FOUND;
A required value/state is false, so the rest of the method does not apply (aka a guard clause). E.g.: if (listeners == null) return null;
The method's purpose is to find and return a specific value, e.g.: if (nodes[i].value == searchValue) return i;
You're in a clause which returns a unique value from the method not used elsewhere in the method: if (userNameFromDb.equals(SUPER_USER)) return getSuperUserAccount();
Otherwise, it is useful to have only one return statement so that it's easier to add debug logging, resource cleanup and follow the logic. I try to handle all the above 4 cases first, if they apply, then declare a variable named result(s) as late as possible and assign values to that as needed.
They both accomplish the same task. Some say that a method should only have one entry and one exit point.
I use this, too. The idea is that resources can be freed in the normal flow of the program. If you jump out of a method at 20 different places, and you need to call cleanUp() before, you'll have to add yet another cleanup method 20 times (or refactor everything)
I guess that the coder has taken the design of defining an object toReturn at the top of the method (e.g., List<Foo> toReturn = new ArrayList<Foo>();) and then populating it during the method call, and somehow decided to apply it to a boolean return type, which is odd.
Could also be a side effect of a coding standard that states that you can't return in the middle of a method body, only at the end.
Even if no code is executed after the return value is assigned now it does not mean that some code will not have to be added later.
It's not the smallest piece of code which could be used but it is very refactoring-friendly.
Delphi forces this pattern by automatically creating a variable called "Result" which will be of the function's return type. Whatever "Result" is when the function exits, is your return value. So there's no "return" keyword at all.
function MethodName : boolean;
begin
Result := False;
if Expression then begin
//do something
Result := MethodCall;
end
else begin
//do something else
Result := Expression;
end;
//possibly more code
end;
The pattern used is verbose - but it's also easier to debug if you want to know the return value without opening the Registers window and checking EAX.

Resources