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

Default to false removeDuplicates when instantiating Readline #842

Merged
merged 3 commits into from
Dec 10, 2024

Conversation

Fludem
Copy link
Contributor

@Fludem Fludem commented Dec 9, 2024

Description

A user experienced this error when using Laravel Tinker:

Cannot assign null to property Psy\Readline\Transient::$eraseDups of type bool
at vendor/psy/psysh/src/Readline/Transient.php:53

Cause of bug

The error is caused by line 53 of Transient.php, where the constructor sets the value of $eraseDups.

The constructor has this signature:

public function __construct($historyFile = null, $historySize = 0, $eraseDups = false)

Types are not declared(Parent does declare). When this constructor is used with the parameters explicitly being null, it will overwrite defaults in PHP8.0 and greater.

In the constructor body, it sets the value of the eraseDups variable.

private bool $eraseDups; // Variable declared at the top of the class

$this->eraseDups = $eraseDups; // Inside the constructor body

This can result in the constructor trying to assign null to the $eraseDups variable. This causes an error as the variable is not declared nullable.

Changes made

Configuration.php

Pass the default value of false when instantiating the ReadLine class in the getReadLine function.

 public function getReadline(): Readline\Readline
    {
        if (!isset($this->readline)) {
            $className = $this->getReadlineClass();
            $this->readline = new $className(
                $this->getHistoryFile(),
                $this->getHistorySize(),
                $this->getEraseDuplicates() ?? false // Added ternary operator to use false if null
            );
        }

        return $this->readline;
    }

The setEraseDuplicates function type casting was removed. It wasn't related to this bug, but the function signature declares the type as bool, making the cast redundant.

$this->eraseDuplicates = (bool) $value; // old
$this->eraseDuplicates = $value; // new

Transient.php

The constructor now sets the value of eraseDups to false if the parameter is null.

$this->eraseDups = $eraseDups ?? false;

The constructor also sets a default history size where the parameter is null.

$this->historySize = $historySize ?? 0;

Updated function signature with types

public function __construct($historyFile = null, ?int $historySize = 0, ?bool $eraseDups = false)

Readline.php (Interface)

Updated constructor signature with more accurate type declarations.

 public function __construct($historyFile = null, ?int $historySize = 0, ?bool $eraseDups = false);

…clared type

(chore) Configuration.php removed redundant type casting on already declared type
bool $eraseDuplicates is nullable which can result in an error when calling getReadLine. Assigned default value of false as fix.

(fix) Null parameter error when instantiating readline

bool $eraseDuplicates is nullable which can result in an error when calling getReadLine. Assigned default value of false as fix.
@Fludem
Copy link
Contributor Author

Fludem commented Dec 9, 2024

Fixes #843

@Fludem
Copy link
Contributor Author

Fludem commented Dec 10, 2024

Few extra notes.

Configuration.php

The erase duplicates property has maintained nullability. I'm not sure why this should or shouldn't be nullable. Leaving it unchanged should avoid breaking anything.

Transient.php

The class property has also maintained its previous nullability.

The history size was also updated to use a default value in the constructor. Previously, it could have caused problems similar to those of erasing duplicates.

@bobthecow bobthecow merged commit 2c9b9a5 into bobthecow:main Dec 10, 2024
27 checks passed
@bobthecow
Copy link
Owner

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants