Hello Sebastian,
for syntax consistency with anonymous functions I would prefer a longer Syntax:
$greet = function ($name) {
printf("Hello %s\r\n", $name);
};
$greet('World');
$log = class {
public function foo() {…
};
$logObj = new $log();
and:
$log = class extends DefaultLog {…
Regards
Thomas
Sebastian Bergmann schrieb am 28. Juni 2014 15:36:
In a unit test, test doubles (dummies, fakes, stubs, spys, and mocks)
are used to simulate the behavior of complex, real objects when a
real object is difficult or impossible to incorporate into a unit
test. A test double can be used anywhere in the program where the
program expects an object of the original class.Traditionally, frameworks and libraries are used to automatically
generate test double objects based on the original objects using
reflection. This idea stems from a time when IDEs were not powerful
enough to do this generation for us.Quoting Robert C. Martin [1]:
"Stubs and spies are very easy to write. My IDE makes it trivial.
I just point at the interface and tell the IDE to implement it.
Voila! It gives me a dummy. Then I just make a simple modification
and turn it into a stub or a spy. [...]I don't like the strange syntax of mocking tools, and the
complications they add to my setups. I find writing my own test
doubles to be simpler in most cases."The more I think about this (especially in the aftermath of the
unserialize()
issue), the more it appeals to me to have "real
code", generated in parts by my IDE, for my test doubles.The question remains, though, where to put this code. Obviously
it belongs with the test suite. But how to name the test double
classes? Unique names are required to be able to have multiple
(differently configured) test doubles for the same original
class. Mocking tools (such as PHPUnit_MockObject, for instance)
use random names for their test double classes.Anonymous classes could be a solution for this problem.
I was surprised to find [2] (and even more so because I voted "No"
on it ... and had no recollection of reading the RFC or voting
on it). Most likely I did not see a use case for anonymous classes
back then.I would like to propose the following syntax for declaring an
anonymous class that does not implement an interface or extend
a class:$o = new {
public function method() {
// ...
}// ...
};
An anonymous class can extend one class or implement one interface.
Unlike non-anonymous classes, an anonymous class cannot do both.
In other words, it cannot both extend a class and implement an
interface, nor can it implement more than one interface.The syntax to have an anonymous class implement an interface or
extend a class is the same:interface AnInterface {
public function method();
}$o = new AnInterface {
public function method() {
// ...
}
}class AClass {
public function method()
{
// ...
}
}$o = new AClass {
// ...
}The ReflectionClass and ReflectionObject classes need to be adapted
for anonymous classes. Only new syntax elements would be added to
the PHP language. Existing elements of the PHP language syntax would
not be changed. No new reserved words would be added to the PHP
language. There should not be an impact on backwards compatibility.In case there is enough positive feedback to the syntax proposed in
this email I would gladly write a formal RFC. I could also help with
writing tests and documentation. Unfortunately I cannot implement the
feature myself.--
[1] http://blog.8thlight.com/uncle-bob/2014/05/14/TheLittleMocker.html
[2] https://wiki.php.net/rfc/anonymous_classes
Hello Sebastian,
for syntax consistency with anonymous functions I would prefer a longer Syntax:
$greet = function ($name) {
printf("Hello %s\r\n", $name);
};
$greet('World');$log = class {
public function foo() {…
};
$logObj = new $log();
I concur that I’d prefer this syntax. I also think it is much more obvious what it does; $x = new {} doesn’t make much sense unless you know of the feature, but $x = class {} isn’t much of a leap from class x {}. Furthermore, I think new {} could be better used for something else.
Also, we could still have the class be immediately instantiated like so:
$foo = new class Bar {};
Or, if the parser wouldn’t permit that:
$foo = new (class Bar {});
Sebastian, do you agree with this?
--
Andrea Faulds
http://ajf.me/