return several values with autocb in iced coffee script - iced-coffeescript

How to return couple values in iced coffee script using return and autocb?
Without autocb I can do:
func = (cb)=>
cb returnVal1, returnVal2
How to implement this using autocb? This code ...
func = (autocb)=>
return returnVal1, returnVal2
... throws error:
SyntaxError: unexpected ,

You are getting an error because you can't return more than one value in JavaScript. You could wrap the two values in an array and destructure it after calling...
func = (autocb)=>
return [returnVal1, returnVal2]
await func defer(returnVals)
[returnVal1, returnVal2] = returnVals
...but you should probably just use your first example. autocb is simple syntactical sugar (one argument instead of one line), and not at all necessary to using IcedCoffeeScript.

Destructuring will work as mentioned here: https://github.com/maxtaco/coffee-script/issues/29
func = (thing, autocb) ->
thing1 = doSomething(thing)
thing2 = doSomethingElse(thing)
{thing1, thing2}
await funct thing, defer {thing1, thing2}
console.log "#{thing1} and #{thing2}"

Related

Is it possible to get a single value from a function (which has multiple return values) during a statement?

Lets say for example add(int, int) returns and int and an error, and I want to append the int return value into a string. The way I know how to do it in go is:
foo := ""
bar, _ := add(1, 2)
foo += strconv.Itoa(bar)
However, if add() didn't return an error variable, I can just do foo += strconv.Itoa(add(1, 2)).
Is it possible to ignore the error variable during the statement to do something like that?
Is it possible to ignore the error variable during the statement to do something like that?
No, Go offers no language construct for something like this.
(But you can have your own Must... functions like you'll find in package regexp or text/template.)
Disclaimer (my opinion): This answer is just for fun. I don't recommend ever using this. Ignoring errors is bad, and trying to compactify every line of code is a fool's errand. This just illustrates some interesting concepts about how Go handles multiple return values, and I learned something new while writing this, so I thought I'd share.
Related: The more practical cousin of this problem is the "Must pattern", used by some of the standard library including templates. It involves taking a value and an error, panicing if the error is not nil, and then returning the value. See this (currently frozen) proposal
You need a wrapper function to do this. The multiple return values will automatically expand to fill the arguments.
See this example which matches the types of add()
func ignoreError(i int, err error) int {
return i
}
Calling:
foo := ""
foo += strconv.Itoa(ignoreError(add(1, 2)))
Here's a more general alternative, which will take any number of values from another function and return the first.
func takeFirstValue(v ...interface{}) interface{} {
if len(v) == 0 {
return nil
}
return v[0]
}
Calling:
foo := ""
foo += strconv.Itoa(takeFirstValue(add(1, 2)).(int))
This option requires casting at the call site .(int) to restore the data type, as takeFirstValue returns interface{}.

How to receive multiple values returned by a method in testify framework "assert" method as an argument?

Below is a sample code , which is returning multiple values .
func (c Calc) CreateTenantHandler(item *models.TenantInput) (*models.Response, *models.ErrorDetails) {
...
...
...
return &models.Response{ResponseStatus: 201, TenantOutput: tenantoutput,}, nil
}
In test file I have tried tried doing below things.
assert.Equal(t,[nil,nil],testObject.CreateTenantHandler(nil) );
I also checked other answers but couldn't find what I need.
You don't. It has nothing to do with testify--that's just how Go works. Set multiple variables to the return values, then assert each one individually:
x, y := testObject.CreateTenantHandler(nil)
assertEqual(t, x, expectedX)
assertEqual(t, y, expectedY)
The issue is that you want to convert several return values into a single value that is usable by assert.Equal.
You can do this by passing multiple values to a variadic function that converts all the values (no matter how many) into a single slice of interfaces. That slice is then treated as a single value and works quite well with testify assert.Equal.
The shim function mentioned elsewhere is close, but it has a fixed number of parameters. makeIS() below is less code, cleaner, simpler and works with any number of return values/parameters. Put this function in your test package.
// makeIS will convert any number of parameters to a []interface{}
func makeIS(v ...interface{}) []interface{} {
return v
}
Now the assert work like this
assert.Equal(t, makeIS(eX,eY), makeIS(iReturnTwoValues())
The testify knows how to make the comparison and reports differences in the individual parameters very well. Notice this has the added benefit of "looking like" the call you want to test with the two target values to the left of the function.
One simple way to do the thing you want is to declare a function like shim:
func shim(a, b interface{}) []interface{} {
return []interface{}{a, b}
}
and then:
assert.Equal(t, shim(5,6), shim(testObject.CreateTenantHandler(nil)));
The behavior is described thoroughly in the link below:
source: http://zacg.github.io/blog/2014/10/05/go-asserts-and-multiple-return-values/
you can add convert function to fix it
package multi_return
import (
"github.com/stretchr/testify/assert"
"testing"
)
func multiReturn() (int, float32) {
return 1, 2
}
func toSlice(a ...interface{}) []interface{} {
return a
}
func TestMultiReturn(t *testing.T) {
assert.Equal(t, []interface{}{int(1), float32(2)}, toSlice(multiReturn()))
}

Empty return in func with return value in golang [duplicate]

This question already has answers here:
How does defer and named return value work?
(3 answers)
Closed 5 years ago.
I was reading some code written in Golang on Github and found a very interesting piece of code. I simplified it to be clear.
func Insert(docs ...interface{}) (err error) {
for i := 0; i < 3; i++ {
err = fmt.Errorf("")
if err.Error()!="EOF" {
return
}
}
return
}
I'm very confused about empty return here... How it works? Does he return nil as error or breaks for loop? I understand that this question looks dummy, but I cannot find any info on this in go docs... Also, I don't understand how we can return err, which is, as I understood, declared somehow in return. Does (err error) means that we already have an error variable available in our func which is used as default return value if none specified? Why then we implicitly make return err at the end of func?
I'll be very gratefull for explanation.
The function uses a "named" return value.
From the spec on return statements:
The expression list may be empty if the function's result type
specifies names for its result parameters. The result parameters act
as ordinary local variables and the function may assign values to them
as necessary. The "return" statement returns the values of these
variables.
Regardless of how they are declared, all the result values are
initialized to the zero values for their type upon entry to the
function. A "return" statement that specifies results sets the result
parameters before any deferred functions are executed.
Using named returns allows you to save some code on manually allocating local variables, and can sometimes clean up messy if/else statements or long lists of return values.
func a()(x []string, err error){
return
}
is really just shorthand for
func a() ([]string,error){
var x []string
var err error
return x,err
}
Its a bit shorter, and I agree that it may be less obvious.
Named returns are sometimes needed, as it allows things like accessing them inside a deferred function, but the naked return is just syntactic sugar as far as I can tell, and is never strictly required.
One place I see it commonly is in error return cases in functions that have many return values.
if(err != nil){
return
}
return a,b,c,nil
is easier than
if(err != nil){
return nil,nil,nil,err
}
return a,b,c,nil
when you have to write it a bunch of times. And you don't have to modify those returns if you change the signature to have additional "real" return values.
Most places I am using them in the codebase I just searched, they definitely seem to be hiding other smells, like overly complex multi-purpose functions, too deep if/else nesting and stuff like that.
Go's return values may be named. If so, they are treated as variables defined at the top of the function.
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
https://tour.golang.org/basics/7
When you have a named return value (err here):
func Insert(docs ...interface{}) (err error) {
This creates a function-local variable by that name, and if you just call return with no parameters, it returns the local variable. So in this function,
return
Is the same as, and implies,
return err
This is detailed in the tour and in the spec.

Understanding enum and function signature

In learning Swift, I came across this code: -
enum ServerResponse {
case Result(String, String)
case Error(String)
}
for i in 1...10{
let mySuccess: ServerResponse = {
let zeroOrOne = rand() % 2
if zeroOrOne == 0 {
return ServerResponse.Result("7:00 am", "8.09 pm")
} else {
return ServerResponse.Error("Out of cheese.")
}
}()
var serverResponse: String
switch mySuccess {
case let .Result(sunrise, sunset):
serverResponse = "Sunrise is at \(sunrise) and sunset as \(sunset)"
case let .Error(error):
serverResponse = "Failure... \(error)"
}
println(serverResponse)
}
As can be seen here, there are parentheses () after the closing end brace of the declaration for:
let mySuccess: ServerResponse = {
...
}()
Without the parenthesis, playground produces the error:-
Function produces expected type 'ServerResponse'; did you mean to call it with ()?
Considering a function has the signature: -
func name(param) -> returnType
Can someone please explain why the parenthesis are required here? Is it a form of minimised closure, or something else?
It's an anonymous function/lambda/closure (however you want to call it exactly), taking no argument, and whose return type is inferred by the compiler, which is then called immediately. It's similar to (function() {ā€¦})() in JavaScript.
It has the big advantage of allowing you to define mySuccess as a constant instead of a variable. Additionally, it creates a scope, such that intermediary variables (like zeroOrOne) are not visible outside.
What I'm wondering is just why the author of this code didn't use the same style to define and assign serverResponseā€¦
Your ServerResponse is not a function, it is an enum, but without the parentheses the block you would be trying to assign to mySuccess IS a function (that returns a ServerResponse), and therefore cannot be assigned to a ServerResponse. The result of calling the function (adding the parentheses) can be.

Pass a result from multi-returing function to another one taking only one argument in Go

Is it possible to pass a result form function which returns multiple values directly to function which accepts only one? Example:
func MarshallCommandMap(mapToMarshall map[string]string) string {
return string(json.Marshal(mapToMarshall))
}
The example above will cause compilation error:multiple-value json.Marshal() in single-value context. I know it is possible to get same result with additional variable:
func MarshallCommandMap(mapToMarshall map[string]string) string {
marshaledBytes, marshalingError := json.Marshal(mapToMarshall)
if (marshalingError != nil) {
panic(marshalingError)
}
return string(marshaledBytes)
}
But is it possible to pass only first value direclty without any variable?
I think you mean doing something like python's tuple unpacking.
Unfortunately this is not possible in Go (AFAIK).
No you can't, however 2 things with your code.
Shouldn't panic, either return an error or return an empty string.
You can make it shorter.
Example :
func MarshallCommandMap(mapToMarshall map[string]string) string {
js, _ := json.Marshal(mapToMarshall) //ignore the error
return string(js)
}

Resources