<commit_before><?php

namespace Memento;

final class Memento
{
    /**
     * 
     * @var unknown_type
     */
    private $name;
    
    /**
     * 
     * @var unknown_type
     */
    private $gender;
    
    /**
     * 
     * @var unknown_type
     */
    private $age;
    
    /**
     * 
     * @var array Memento objects in LIFO stack
     */
    private $revisions = array();
    
    public function __get($name)
    {
        //
        if (property_exists($this, $name)) {
            return $this->$name;
        }
        return null;
    }
    
    public function __set($name, $value)
    {
        //
        if (property_exists($this, $name)) {

            //
            $clone = clone($this);
            $this->addRevision($clone);
            
            //
            $clone->$name = $value;
        }
    }
    
    public function commit()
    {
        //
        $latest = array_pop($this->revisions);
        
        //
        foreach (get_object_vars($latest) as $property => $value) {
            
            //
            $this->$property = $value;
        }
        
        $this->revisions = array();
    }
    
    public function rollback($depth = 0)
    {
        //
        if ((integer) $depth > 0) {
            
            //
            for ($x = 1; $x <= $depth; $x++) {
                array_pop($this->revisions);
            }

        //
        } else {
            $this->clearRevisions();
        }
    }
    
    private function addRevision(self $object)
    {
        $this->revisions[] = $object;
    }
    
    private function clearRevisions()
    {
        $this->revisions = array();
    }
}<commit_msg>Finished Memento class<commit_after><?php

namespace Memento;

/**
 * Memento design pattern
 * 
 * There are various ways of tracking the changes made to an object, many that
 * are more graceful and performant than this, but this should demonstrate a 
 * relatively simple way to track the changes made to an object in a 
 * transactional way
 * @author <NAME> <<EMAIL>>
 */
final class Memento
{
    /**
     * Name (of the thing)
     * @var string
     */
    private $name;
    
    /**
     * Gender (or sex if you're from a bygone era)
     * @var string
     */
    private $gender;
    
    /**
     * Age (in human years, not dog years)
     * @var integer
     */
    private $age;
    
    /**
     * Revision history of current Memento object
     * @var Memento[] Memento objects in LIFO stack
     */
    private $revisions = array();
    
    /**
     * Get a property
     * @param string $name
     * @return mixed|null
     */
    public function __get($name)
    {
        //
        if (property_exists($this, $name)) {
            return $this->$name;
        }
        return null;
    }
    
    /**
     * Set a property
     * @param string $name
     * @param mixed $value
     */
    public function __set($name, $value)
    {
        // If the property exists...
        if (property_exists($this, $name)) {

            // Clone the current object and add as a revision
            $clone = clone($this);
            $this->addRevision($clone);
            
            // Set the property
            $this->$name = $value;
        }
    }
    
    /**
     * Commit changes (discard all previous revisions)
     * 
     * Discards the previous revisions of this object so that changes are now 
     * final
     */
    public function commit()
    {
        $this->clearRevisions();
    }
    
    /**
     * Rollback changes
     * @param integer $depth How many revisions to rollback
     */
    public function rollback($depth = 0)
    {
        // If no depth is specified, rollback to the oldest revision
        if ((integer) $depth <= 0) {
            $depth = count($this);
        }
            
        // Pop revisions from the stack until the specified depth is reached
        for ($x = 1; $x <= $depth; $x++) {
            $rollbackRevision = array_pop($this->revisions);
        }
        
        // Iterate over each property of the revision
        foreach (get_object_vars($rollbackRevision) as $property => $value) {
        
            // Set the property of the current object to that of the revision
            $this->$property = $value;
            
        }
    }
    
    /**
     * Add a revision
     * @param self $object
     */
    private function addRevision(self $object)
    {
        $this->revisions[] = $object;
    }
    
    /**
     * Clear revisions
     */
    private function clearRevisions()
    {
        $this->revisions = array();
    }
}
{'fraction_non_alphanumeric': 0.1183380465520992, 'fraction_numerical': 0.0013051990428540352, 'mean_word_length': 1.430232558139535, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2937608', 'n_tokens_mistral': 1361, 'n_tokens_neox': 1312, 'n_words': 367}