📜 ⬆️ ⬇️

Soul in the program

Remember the beginning of the film "I am a robot"? There, the professor gives a lecture on the phenomenon of "Soul" in the program code:

“When a program grows, especially when many people are involved in it, pieces of the so-called“ dead code ”inevitably begin to occur. These are the remaining functions that have been replaced by newer ones or just the test code forgotten by the programmer.
When such critical mass accumulates of such pieces, it can lead to unexpected actions in the algorithm, which, from the outside, can be called a manifestation of one's will or “Soul” of the program ”

The quotation does not claim to be accurate, but the sense is as follows. In light of this and recent topics in Habré to check variable names for different values ​​in different languages ​​(sorry, I could not find the link), I decided to describe a small incident that happened to me. Perhaps, if someone also met with "manifestations of the soul", which turned out to be the most banal errors in the code, he would want to throw an example to a comment or give me an invite.

So, the essence of the matter fits in one function - handling the TextChanged event. Processing is that when you receive a particular character, you must add a certain line after the cursor position.
')
At first, the handler looked like this:

private void txtMain_TextChanged( object sender, EventArgs e)<br>{<br> //, ( backspace - ) <br> if (txtMain.Text.Length > textlen)<br> {<br> // <br> if (txtMain.Text[txtMain.TextLength - 1] == 'a' )<br> {<br> // try - <br> try <br> {<br> string newSpace = "<inputted a>" ; //- <br> int curPosition = txtMain.SelectionStart; // <br> txtMain.Text = txtMain.Text.Insert(curPosition, newSpace); // <br> txtMain.SelectionStart = curPosition + newSpace.Length; // <br> }<br> catch (Exception ex)<br> {<br> MessageBox.Show(ex.Message); // <br> }<br> }<br> }<br> textlen = txtMain.Text.Length; // , <br>} <br><br> * This source code was highlighted with Source Code Highlighter .


But the first error was found quite simply - the line was not inserted if the required character was entered in the middle of the typed text. Those. Only the last character was checked. Then the 7th line was corrected as follows:

if (txtMain.Text[txtMain.SelectionStart - 1] == 'a' ) <br><br> * This source code was highlighted with Source Code Highlighter .


And here the most interesting thing began - the method began to throw IndexOutOfRangeException on line 14:
txtMain.Text = txtMain.Text.Insert(curPosition, newSpace);// <br><br> * This source code was highlighted with Source Code Highlighter .


At the same time, when entering a function (for the case of sequential text input - that is, when we add the required character to the end) in both cases both properties had the same value - both TextLength and SelectionStart. Passing through the body of the function was the same, but in the case of SelectionStart, an exception was dropped.

I could not understand for a long time why, changing in one line the name of a property that returns the same value as the previous one, I get an exception 5 lines below.

But it turned out pretty simple. At the moment of inserting the desired line (just the place where the exception fell), the TextChanged event was raised again (logical !!) but for him SelectionStart was 0, as a result, we received an attempt to compare the -1 character of the string with the specified one, but the debugger showed an error on 14 line, and not on the 7th.

Actually, the final function code is as follows:

private void txtMain_TextChanged( object sender, EventArgs e)
{
//, ( backspace - )
//
if (txtMain.Text.Length > textlen && txtMain.SelectionStart > 0)
{
//
if (txtMain.Text[txtMain.SelectionStart - 1] == 'a' )
{
// try -
try
{
string newSpace = "<inputted a>" ; //-
int curPosition = txtMain.SelectionStart; //
txtMain.Text = txtMain.Text.Insert(curPosition, newSpace); //
txtMain.SelectionStart = curPosition + newSpace.Length; //
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); //
}
}
}
textlen = txtMain.Text.Length; // ,
}


* This source code was highlighted with Source Code Highlighter .

Source: https://habr.com/ru/post/84865/


All Articles