Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[enh] Proposal to add class StringObject #6

Open
rugabarbo opened this issue Jun 15, 2019 · 14 comments
Open

[enh] Proposal to add class StringObject #6

rugabarbo opened this issue Jun 15, 2019 · 14 comments
Labels
status:ready for adoption Feel free to implement this issue. type:feature New feature

Comments

@rugabarbo
Copy link
Member

I propose to add class StringObject. Then it will be possible to manipulate strings in object-oriented style:

$baseWord = new StringObject('soft', 'UTF-8');

$projectName = $baseWord
   ->preprend('yii')
   ->addWord('project')
   ->upperCaseEveryWord();

$projectNameWordsCount = $projectName->wordsCount();

Then we can make class StringHelper a wrapper over class StringObject. For example:

class StringHelper
{
    public static function createObject(string $string, string $encoding = null): StringObject
    {
        return new StringObject($string, $encoding);
    }

    public static function wordsCount(string $string, string $encoding = null): int
    {
        return static::createObject($string, $encoding)->wordsCount();
    }
}
@loveorigami
Copy link

You can use it https://github.com/fe3dback/str

@rugabarbo
Copy link
Member Author

rugabarbo commented Jun 15, 2019

@loveorigami I know about this lib. Thanks. But I am talking about the future of this library.

There are many other good string processing libraries. But they have one problem - the authors stop supporting them. For example, there is an excellent library Stringy – but project is dead because author stopped supporting it. There's no code commits since 2017.

If Yii team isn't going to support and develop this library, then it should be replaced now with some kind of external solution. If the team is going, then I suggest an object-oriented design.

@rugabarbo
Copy link
Member Author

BTW library https://github.com/fe3dback/str is also rarely updated (only 3 commits for 2019) and still has no documentation and has no implementation of a static wrapper. I would not choose it for a long-term project.

@samdark
Copy link
Member

samdark commented Jun 15, 2019

What's the benefit in wrapping strings into objects?

@rugabarbo
Copy link
Member Author

rugabarbo commented Jun 15, 2019

What's the benefit in wrapping strings into objects?

  1. An object has a state. This allows you to set the encoding only once.
  2. Fluent interface is more convenient when you need a series of calls.

Just compare:

a) Using object:

$sentence = StringHelper::createObject($input, 'UTF-8')
    ->trim()
    ->upperCaseFirst()
    ->ensureLastSymbol('.');

b) Using static helper:

$encoding = 'UTF-8';

$buffer = StringHelper::trim($input, $encoding);
$buffer = StringHelper::upperCaseFirst($buffer, $encoding);
$buffer = StringHelper::ensureLastSymbol($buffer, '.', $encoding);

$sentence = $buffer;

On the other hand static methods are useful when a callable parameter is required:

public function rules()
{
    return [
        [['title', 'short_description'], 'filter', 'filter' => StringHelper::class . '::collapseWhitespaces'],
        [['title', 'short_description'], 'trim'],
        [['title', 'short_description'], 'required'],
        [['title', 'short_description'], 'string', 'max' => 128],
    ];
}

Here it would be very inconvenient to use a string object.


Therefore, it is convenient to have both an object interface for strings and a static wrapper in the same library.

@samdark
Copy link
Member

samdark commented Jun 16, 2019

@yiisoft/core-developers, @yiisoft/reviewers opinions?

@rob006
Copy link

rob006 commented Jun 16, 2019

Any benchmarks to measure overhead?

@rugabarbo
Copy link
Member Author

Any benchmarks to measure overhead?

@rob006 what kind of overhead do you mean? In such libraries, the main performance losses are the result of poor implementation, but not the result of using objects.

Implementation is a separate problem. This can be bad in both object-oriented style and static methods.

@rob006
Copy link

rob006 commented Jun 17, 2019

@rob006 what kind of overhead do you mean? In such libraries, the main performance losses are the result of poor implementation, but not the result of using objects.

I believe that creating objects and additional function calls will result noticeable overhead compared to simple operations on scalars. Especially if you want to use it internally in this way:

    public static function wordsCount(string $string, string $encoding = null): int
    {
        return static::createObject($string, $encoding)->wordsCount();
    }

@rugabarbo
Copy link
Member Author

Do you mean memory overhead or performance overhead?

@rob006
Copy link

rob006 commented Jun 17, 2019

Performance (CPU).

@rugabarbo
Copy link
Member Author

In order not to create a large number of objects during a series of static calls, we can implement it a little differently:

class StringHelper
{
    public static function wordsCount(string $string, string $encoding = null): int
    {
        // Simple operations on scalars here

        return $count;
    }
}

class StringObject
{
    protected $string;
    protected $encoding;

    public function __construct(string $string, string $encoding = null)
    {
        $this->string = $string;
        $this->encoding = $encoding;
    }

    public static function create(string $string, string $encoding = null): StringObject
    {
        return new static($string, $encoding);
    }

    public function wordsCount(): int
    {
        return StringHelper::wordsCount($this->string, $this->encoding);
    }
}

If you are worried about the performance of static calls, then this design will solve the problem. So, performance depends on the concrete implementation.

@machour machour added the type:feature New feature label Jun 23, 2019
@voku
Copy link

voku commented Jun 26, 2019

Hi, I merged performance improvements from the str lib into a maintained fork of Stringy + fixes from the community. Maybe you can find there some inspirations?! ☺ https://github.com/voku/Stringy

@samdark
Copy link
Member

samdark commented Aug 26, 2020

Can be implemented later as a wrapper for StringHelper.

@samdark samdark added the status:ready for adoption Feel free to implement this issue. label Aug 26, 2020
@samdark samdark added this to the 1.1.0 milestone Sep 19, 2020
@samdark samdark removed this from the 1.1.0 milestone Jan 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:ready for adoption Feel free to implement this issue. type:feature New feature
Projects
None yet
Development

No branches or pull requests

6 participants