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()
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()
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
childClass::customMethod()
has different arguments, or a different access level (public/private/protected) than parentClass::customMethod()
.
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.
There are a few ways of going about this. Here are two of them.
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)
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)
You can harness
__call
for this: