...

/

Creating a String Cursor Using Additional Utility Methods

Creating a String Cursor Using Additional Utility Methods

Learn how to create a string cursor with the help of additional utility methods.

Implementing additional utility methods

This section will add additional methods to the existing code.

Press + to interact
<?php
abstract class AbstractStringCursor
{
// ...
public function continue(): bool
{
return true;
}
public function break(): bool
{
return false;
}
public function append($content)
{
$this->buffer .= $content;
return $this;
}
public function popBuffer()
{
$this->buffer = str($this->buffer)->substr(0, -1);
return $this;
}
public function clearBuffer()
{
$this->buffer = '';
return $this;
}
public function flushBuffer()
{
$contents = $this->buffer;
$this->buffer = '';
return $contents;
}
/**
* Indicates if the cursor completed its traversal.
*
* @return bool
*/
public function didProcess(): bool
{
return ! $this->shouldReset;
}
// ...
}

Most of our new methods interact with the internal string buffer somehow. For example, the popBuffer will remove the last character of the buffer for us. The flushBuffer and clearBuffer methods are similar, with the difference being the flushBuffer method will return the buffer contents while the clearBuffer variant will not.

The continue and break methods are arguably the simplest methods we add but allow us to dramatically improve the readability of cursor implementations. For example, the following returns false when we want to stop processing the input text:

Press + to interact
<?php
$iterator = new Utf8StringIterator(
'one, two, "three"'
);
$closeCursor = new ClosureStringCursor($iterator);
foreach ($iterator as $char) {
if ($char == '"') {
$result = $closeCursor->traverseUsing(function ($current) {
if ($current == '"' && $this->index > 0) {
return false;
}
});
}
}

However, if you came across this code and were not entirely familiar with what exactly is going on, this might seem a bit puzzling at first. We can refactor this to use our break ...