1

I'm following this tutorial which is giving me this code:

"Run the module `hello.ceylon`."
shared void run() {
    process.write("Enter a number (x): ");
    value userX = process.readLine();
    value x = parseFloat(userX);
    process.write("Enter a number (y): ");
    value userY = process.readLine();
    value y = parseFloat(userY);

    if (exists x, exists y) {
        print("``x`` * ``y`` = ``x * y``");
    } else {
        print("You must enter numbers!");
    }
}

But it gives me this message:

Argument must be assignable to parameter string of parseFloat: String? is not assignable to String

I have copy/paste'd this code but still the same message.

Renato
  • 12,940
  • 3
  • 54
  • 85
rubenh
  • 21
  • 1

2 Answers2

3

I am the author of the tutorial.

I'm terribly sorry that this sample code does not work anymore (it worked with Ceylon 1.0.0, see below).

I have fixed it in the tutorial and created a runnable sample in the Ceylon Web IDE which you can use to try this out.

Basically, the problem is that, as Lucas Werkmeister pointed out, readLine() return a String? which is equivalent to String|Null because it may not be possible to read anything from the input (user's keyboard), in which case you get null back.

The code sample worked with Ceylon 1.0.0 because readLine() used to return a String.

So for the code to compile, you need to make sure to check that what you got back exists (ie. is NOT null):

value userX = process.readLine();
value x = parseFloat(userX else "");

When you do userX else "", you tell Ceylon that if userX exists, it should use that, if not, use "" instead. This way, we always get a String back...

The whole code snippet should look like this (see the sample linked to above):

process.write("Enter a number (x): ");
value userX = process.readLine();
value x = parseFloat(userX else "");
process.write("Enter a number (y): ");
value userY = process.readLine();
value y = parseFloat(userY else "");

if (exists x, exists y) {
    print("``x`` * ``y`` = ``x * y``");
} else {
    print("You must enter numbers!");
}

Thank you for reporting the error! Hope you enjoy the rest of the tutorial.

Renato
  • 12,940
  • 3
  • 54
  • 85
1

process.readLine() returns a String?, that is, a String if it could read a line, or null if not (for example, end of stream). parseFloat requires a non-optional String: parseFloat(null) is not allowed. So you have to assert that userX exists:

assert (exists userX = process.readLine());

or

value userX = process.readLine();
assert (exists userX);

Both forms make userX a non-optional variable.

Lucas Werkmeister
  • 2,584
  • 1
  • 17
  • 31