The feature is: multi-line input. Using the conventional line-by-line approach, there were several uncomfortable issues with entering longer chunks of code, like a class definition. It was possible to do the following:
After pressing enter after the first line, cling notices that the input was not complete and waits for you to enter more code until the declaration is complete.struct Struct { //press enter int m_i; //press enter Struct():m_i(0){} //press enter }; //press enter
Problem:
But let's just cope with that.
So entering multiple lines has always been possible, cling will notice if my input is complete or not, right? So one might assume that the following works:
Assume "inst" is an instance of a class (let's call it Struct again) implementing the named parameter idiom and your intent is to write sth like:
And you'd assume that it also works this way:inst.setA(1).setB(5).setC("foo");
...as would be legal C++. Well, not quite.inst.setA(1) //press enter .setB(5) //press enter .setC("foo"); //press enter
The problem: Cling has a nice feature. If you enter a statement that has no trailing semicolon, cling will notice that, add the semicolon and print the value of the expression if it is or returns a value.
So this:
will print:functionReturningIntOfValueFive() //note: no semicolon
Thus, after entering the first line in our "inst"-example above will print:(int) 5
because Struct::setA() returns a reference to itself. And qling chokes on the lines after that one.(struct Struct) @0x7fbd13380024
Multi-line input to the rescue:
The code-input is not a simple QLineEdit anymore, it is now a QTextEdit with no vertical scrollbar that adjusts its height to fit the text. So you can now enter a whole chunk of code and navigate and edit the (yet unsubmitted) code as you would expect from a proper text-edit. Only after pressing Ctrl+Enter, the code will be submitted.
Note: since the arrow keys are now needed for navigating in the text, you need to press Ctrl+KeyUp and Ctrl+KeyDown to move in the history.
So, I can just paste whole source-files in the code-edit and be happy?...well, not quite. There is another point worth mentioning:
Preprocessor directives such as #include or #define need to be submitted separately from simple statements such as function calls. So in a nutshell if you enter the following:
the input is split in two chunks: the first 5 lines containing the preprocessor directives and the last line. These two chunks are interpreted separately. That's fine and works, the output is "blubb: 1" as one would expect.#define HULA #ifdef HULA #define BLUBB 1 #endif #include <iostream> std::cout<<"blubb: "<<BLUBB<<std::endl;
Whereas the following fails:
The nitty-gritty details about why this fails will be explained in the next blog-post, this one is getting a little long...#ifdef HULA struct MaybeHula{void foo(){std::cout<<"Hula defined\n";}}; #else struct MaybeHula{void foo(){std::cout<<"Hula NOT defined\n";}}; #endif
Keine Kommentare:
Kommentar veröffentlichen