An oddity in vi
I do now know the answer, it was provided quite quickly,
and with references to a longer discussion. I intend to write
a follow-up to this, with that explanation and my thoughts on
it. Still feel free to email me or use the comment box to pass
on your thoughts, but as I say, I do now know what's going on.
That doesn't mean I like it ... |
I'm going to tell you a story, so this is quite a long post. If
you'd like to skip the story get directly to the main point then
feel free to do so.
But if you're interested in the story, are you sitting comfortably?
Then I'll begin.
Don't judge me ...
Don't judge me, but I like cricket. There are different forms of
the game, and each has its own merits and drawbacks. The problem
is that sometimes there's a game I'm interested in, but I only
have access to, or time for, a highlights program. And they
bounce around so much it can be tricky to keep track of how well
each team is doing. I really find it useful when they display
the "scoring worm" diagram, but they don't show that as often as
I want.
For those who don't know, it won't really matter, but a
One Day International (ODI) game usually consists of each team
batting once. The bowling team gets a total of 300 "Deliveries"
or "Balls" to bowl at them. These are delivered in batches of
six, each batch of six is called an "Over" and is delivered by
one bowler. A bowler may not deliver consecutive Overs, and
each bowler is restricted to at most 10 Overs, so at least 5
different bowlers must be used in a game of 50 Overs.
|
So I wrote my own.
Of course.
I started by having a file with lines giving:
I call this a "context" ... it tells us (most of) the current
situation, the context of the next ball.
So the program just reads those triples, converts the second and
third to a distance along the X axis, the first number into the
height, plot that, and we a scoring worm:
To be clear, a team's "Score" is the total accumulation
of "Runs". A "Run" can be credited to the team by the batters
changing ends (running between the wickets) but also by various
penalties due to infringements by the bowler, such as "Wides",
"No Balls", and similar. But the "Score" is the accumulation
of "Runs". |
Here we can see the scoring by Afghanistan on Jan 21${}^{st}$,
2021. They batted first against Ireland, and you can see that
I've included lines for scoring at 4, 5, or 6 runs per Over.
You'll also see cross-ticks. They indicate when wickets fall,
and since you have to stop batting when you lose ten wickets,
there's a balance between taking a risk, trying to score quickly,
and running out of batters, versus taking your time, preserving
your resource, and possibly running out of time.
It is possible to lose a wicket without the number of
balls bowled being advanced, and it's possible to score a run
despite a wicket being lost!
No, it's not at all mysterious, but if someone tries to explain
it all in dribs and drabs it can give that impression. But in
truth, it's all logical and consistent. Or at least, as logical
and consistent as any sport can be.
|
But I needed to be able to put the fall of a wicket in my file.
I did that simply by putting a "W" on a line by itself. That
could then be proceeded by the context (score/overs/balls), and
then when the wicket fell it was implicitly no extra score and
one extra ball. So I could put:
151 29 2
W
151 29 3
The third line there isn't strictly necessary, but it makes
sense to have it.
More syntax
Sometimes the coverage is really, really annoying, and they
don't put the actual score up for minutes at a time, but they
do show the runs being scored. So sometimes I know the score
at the beginning of an Over, and I know what happens on each
ball, so it makes sense to have that as an option. Here's an
entire Over from that game:
I now have everything I need to record the "worm" even
when there are wides, no-balls, and more. You may choose to
think how that's done. When you see it, it's not hard. |
168 35 0
1
0
1
2
0
1
173 36 0
Compacting the format
The file was starting to become quite long, and I thought it
convenient to have the scores from a complete Over all on one
line. So the above became this:
168 35 0
1 0 1 2 0 1
173 36 0
Pressing "J" joins "this" line with the
next line, with a space (or two!) between them. |
In vi (strictly, vim, but I won't quibble) it was easy to
score in the longer form, then use "J" multiple times to put
all the balls on a single line. The last line isn't strictly
needed as it can be deduced from the previous two, but it was no
problem, and reflected the scores being reported on the screen
in the coverage.
But now we get to our small mystery.
What ?!? Why ???
So I would position the cursor on the line containing the first
ball of the Over, then press "J" five times to pull up each of
the five other lines to join this one.
"Well," I thought, "vi has the option of putting a multiple in
front of a command and it executes the command that many times.
So if I type "5J" then it will all happen all at once."
So I typed "5J". Here is the before and after:
168 35 0
1
0
1
2
0
1
173 36 0
|
|
->
|
168 35 0
1 0 1 2 0
1
173 36 0
|
|
What?
So in this case, pressing J five times does not give the same
result as pressing "5J". Instead, one needs to enter "6J", and
that seems, to me, completely inconsistent.
My Mental Model ...
I'm getting some feedback, and it looks like:
- My mental model was wrong;
- I'm not alone in this;
- Others have also been surprised;
- It is "expected behaviour";
- It's more complicated than you might hope.
I'll update this as more information comes in.
|
So my mental model of commands in vi is that "nC" is the same
as executing "C" n times. But in this case it isn't. So
either the internal command interpreter is not what I thought
it was, or the designers have explicitly made an exception in
this case.
What other exceptions exist? Why should this be an exception
at all?
I really just don't understand.
And that is the oddity I found in vi.
Addendum
Afghanistan won:
Send us a comment ...
|