How to fix the Ruby code which a splatting array as parameter

Following is a code example:

instances_restarted.push(*stopped)

I get error message like this:

 127 | instances_restarted.push(*stopped)
                                 ^
Error: argument to splat must be a tuple, not Array(Array(Procodile::Instance | Nil))

The above stopped is a array, neither know the type of it element is, nor the size of stopped.

the element of stopped want to pushed into another array instances_restarted.

At least, if this array have 100 elements, i consider write code like: Tuple(Procodile::Instance, Procodile::Instance, Procodile::Instance, ...).from(stopped)) is not accepted.

So, how to fix this?

As the error says, you can only splat a Tuple. I’m pretty sure you could just do instances_restarted.concat stopped to have the same behavior on this context tho. This would be basically the same as if you iterated over the array and << each item.

The solution is simply that instances_restarted.push must be implemented in a way that it accepts a dynamic collection instead of just a compile time splat argument.

instances_restarted.concat stopped to have the same behavior on this context

Okay, thanks, i fix it use concat, but, before i ask this question here, it try it, but not work because some type issue, those error message a little confusing, at that time, I didn’t have time to research why those wired error raised.

In /home/zw963/Crystal/share/crystal/src/array.cr:754:39

 754 | (@buffer + @size).copy_from(other.to_unsafe, other_size)
                                         ^--------
Error: expected argument #1 to 'Pointer(Procodile::Instance)#copy_from' to be Pointer(NoReturn) or Pointer(Procodile::Instance), not Pointer(Array(Procodile::Instance | Nil))

Overloads are:
 - Pointer(T)#copy_from(source : Pointer(NoReturn), count : Int)
 - Pointer(T)#copy_from(source : Pointer(T), count : Int)

after some research, I guess i understood the purpose of this (@buffer + @size).copy_from(other.to_unsafe, other_size) here, and where is the @buffer or @size come from.

anyway, i consider those error not so friendly, for a user who just want to use Array#concat.

Yes, this error message is not very helpful. It spills implementation details instead of giving a clear high level error indication.
Ideally this would be solved by validating generic type argument restrictions.

2 Likes

Array#concat isn’t the only thing that causes this type of error unfortunately. I think the gist of it tho is that there is a type mismatch between the array you’re concatting into and from. Looks like stopped may include nil values while instances_restarted doesn’t or something like that?

Looks like stopped may include nil values while instances_restarted doesn’t or something like that?

Yes, you are right, But those too many of irrelevant error messages made me ignore it.

You should always use --error-trace and scan the backtrace to see where the error was first introduced.

Given that Crystal is almost like a dynamic language at compile-time… in Ruby if you get a “type error” you see all the backtrace to see where, for example, you introduced a nil value.

In Crystal that was the case before! You could always see the backtrace. Now that is hidden behind --error-trace so you get errors that are confusing, like this one.

I hope the core team realizes that’s a mistake, and always show the full backtrace, and remove the --error-trace option.

Imagine coding in Ruby and when you get an exception you only see the last frame…

Yes, it hidden the back trace which including the error raised from.

I hope the core team realizes that’s a mistake, and always show the full backtrace, and remove the --error-trace option.

another option is, make user use --error-trace more easiler. :smile:, i create a issue several days ago, this solution is so easy even i can add it with in minutes, with not breaking everything.

In fact, i have already worked around it in my local laptop use a bash script as wrapper as i said the issue.

BTW: i still consider the key issue is, we need handle this case with a more better error message.