Viewed   85 times

How do I add a new method to an object "on the fly"?

$me= new stdClass;
$me->doSomething=function ()
 {
    echo 'I've done something';
 };
$me->doSomething();

//Fatal error: Call to undefined method stdClass::doSomething()

 Answers

1

You can harness __call for this:

class Foo
{
    public function __call($method, $args)
    {
        if (isset($this->$method)) {
            $func = $this->$method;
            return call_user_func_array($func, $args);
        }
    }
}

$foo = new Foo();
$foo->bar = function () { echo "Hello, this function is added at runtime"; };
$foo->bar();
Saturday, August 6, 2022
1

To answer your cat example, your cat's methods need to return $this, which is the current object instance. Then you can chain your methods:

class cat {
 function meow() {
  echo "meow!";
  return $this;
 }

 function purr() {
  echo "purr!";
  return $this;
 }
}

Now you can do:

$kitty = new cat;
$kitty->meow()->purr();

For a really helpful article on the topic, see here: http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html

Monday, October 24, 2022
3

childClass::customMethod() has different arguments, or a different access level (public/private/protected) than parentClass::customMethod().

Friday, September 23, 2022
 
theraot
 
4

You can define a new class in your application at lib/ext/string.rb and put this content in it:

class String
  def to_magic
    "magic"
  end
end

To load this class, you will need to require it in your config/application.rb file or in an initializer. If you had many of these extensions, an initializer is better! The way to load it is simple:

require 'ext/string'

The to_magic method will then be available on instances of the String class inside your application / console, i.e.:

>> "not magic".to_magic
=> "magic"

No plugins necessary.

Friday, December 9, 2022
 
jemus42
 
1

There are a few ways of going about this. Here are two of them.

  1. To go along with your existing code, split the path by '.', then iterate over them. If the path is not there, create it with Add. Otherwise, if we're on the last part of the path, just add the value.

    var json = JObject.Parse(@"{""DanaerysTargaryen"":{""Dragons"":{""Dragon1"":{""Name"": ""Drogon""}},""Hair"": {""Color"": ""White""}}}");
    var toAdd = "DanaerysTargaryen.Dragons.Dragon1.Color";
    var valueToAdd = "Black";
    var pathParts = toAdd.Split('.');
    JToken node = json;
    for (int i = 0; i < pathParts.Length; i++)
    {
        var pathPart = pathParts[i];
        var partNode = node.SelectToken(pathPart);
        if (partNode == null && i < pathParts.Length - 1)
        {
            ((JObject)node).Add(pathPart, new JObject());
            partNode = node.SelectToken(pathPart);
        }
        else if (partNode == null && i == pathParts.Length - 1)
        {
            ((JObject)node).Add(pathPart, valueToAdd);
            partNode = node.SelectToken(pathPart);
        }
        node = partNode;
    }
    
    Console.WriteLine(json.ToString());
    

(Example on dotnetfiddle.net)

  1. Otherwise, you could create a separate JObject that represents the node(s) you want to add, then merge them.

     var json = JObject.Parse(@"{""DanaerysTargaryen"":{""Dragons"":{""Dragon1"":{""Name"": ""Drogon""}},""Hair"": {""Color"": ""White""}}}");
     var toMerge = @"{""DanaerysTargaryen"":{""Dragons"":{""Dragon1"":{""Color"":""Black""}}}}";
     var jsonToMerge = JObject.Parse(toMerge);
     json.Merge(jsonToMerge);
     Console.WriteLine(json.ToString());
    

(Example on dotnetfiddle.net)

Thursday, December 22, 2022
 
ffxsam
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :