/**
  * merge their data into one of our object's properties
  *
  * @param  object &$obj
  *         the object that we want to merge into
  * @param  string $property
  *         the property to merge into
  * @param  mixed $value
  *         the data that we want to merge from
  * @return void
  */
 public static function ofObject($obj, $property, $value)
 {
     // robustness!
     RequireAssignable::check($obj, E4xx_UnsupportedType::class);
     // easiest case - no clash
     if (ShouldOverwrite::intoObject($obj, $property, $value)) {
         $obj->{$property} = $value;
         return;
     }
     // special case - we are merging into an object
     if (is_object($obj->{$property})) {
         MergeIntoAssignable::from($obj->{$property}, $value);
         return;
     }
     // if we get here, then we must be merging into an array
     MergeIntoIndexable::from($obj->{$property}, $value);
 }
 /**
  * merge their object into our array
  *
  * @param  array &$ours
  *         the array that we want to merge into
  * @param  object $theirs
  *         the object that we want to merge from
  * @return void
  */
 public static function fromObject(&$ours, $theirs)
 {
     // robustness!
     RequireAssignable::check($theirs, E4xx_UnsupportedType::class);
     self::fromArray($ours, get_object_vars($theirs));
 }
 /**
  * merge their data into our object, using dot.notation.support to
  * find the point where the merge starts
  *
  * @param  object $obj
  *         the object that we want to merge into
  * @param  string $path
  *         the dot.notation.support path to where the merge should start
  * @param  mixed $value
  *         the data that we want to merge from
  * @param  array|callable|string|null
  *         if $path goes beyond what exists in $ours, how do we want to
  *         extend $ours?
  * @return void
  */
 public static function intoObject($obj, $path, $value, $extendingItem = null)
 {
     // robustness!
     RequireAssignable::check($obj, E4xx_UnsupportedType::class);
     RequireDotNotationPath::check($path);
     // find the point where we want to merge
     list($firstPart, $finalPart) = self::splitPathInTwo($path);
     if ($firstPart !== null) {
         $leaf =& DescendDotNotationPath::intoObject($obj, $firstPart, $extendingItem);
     } else {
         $leaf = $obj;
     }
     // merge it
     MergeIntoProperty::of($leaf, $finalPart, $value);
 }
 /**
  * does $path point to a valid piece of data inside $container?
  *
  * @param  object $container
  *         the container to look inside
  * @param  string $path
  *         the dot.notation.support path to walk
  * @return boolean
  *         TRUE if $path points to a vlaid piece of data
  *         FALSE otherwise
  */
 public static function inObject($container, $path)
 {
     // defensive programming!
     RequireAssignable::check($container, E4xx_UnsupportedType::class);
     RequireAnyOneOf::check([new IsDotNotationPath(), new IsStringy()], [$path], E4xx_NotDotNotationPath::class);
     try {
         DescendDotNotationPath::intoObject($container, $path);
         return true;
     } catch (E4xx_NoSuchIndex $e) {
         return false;
     } catch (E4xx_NoSuchProperty $e) {
         return false;
     }
 }
 /**
  * extract a value from an object, using dot.notation.support
  *
  * @param  object $obj
  *         the object to extract from
  * @param  string $property
  *         the dot.notation.support path to walk
  * @return mixed
  *         whatever we find when we walk the path
  */
 public static function fromObject($obj, $property)
 {
     // robustness!
     RequireAssignable::check($obj, E4xx_UnsupportedType::class);
     return DescendDotNotationPath::intoObject($obj, $property);
 }
 /**
  * descend inside an object, using dot.notation.support, and optionally
  * extending the object if the end of the dot.notation.path is missing
  *
  * @param  object $obj
  *         the object to dig into
  * @param  string $property
  *         the dot.notation.support path to descend
  * @param  array|callable|string|null $extendingItem
  *         if we need to extend, what data type do we extend using?
  * @return mixed
  */
 public static function &intoObject($obj, $property, $extendingItem = null)
 {
     // robustness!
     RequireAssignable::check($obj, E4xx_UnsupportedType::class);
     RequireStringy::check($property, E4xx_UnsupportedType::class);
     if (strlen($property) === 0) {
         throw new \InvalidArgumentException("'\$property' cannot be empty string");
     }
     $retval =& self::getPathFromRoot($obj, $property, $extendingItem);
     return $retval;
 }
 /**
  * @covers ::check
  * @covers ::checkMixed
  * @dataProvider provideNonAssignables
  * @expectedException GanbaroDigital\Reflection\Exceptions\E4xx_UnsupportedType
  */
 public function testRejectsNonAssignablesWhenCalledStatically($item)
 {
     // ----------------------------------------------------------------
     // setup your test
     // ----------------------------------------------------------------
     // perform the change
     RequireAssignable::check($item);
 }