On 11/5/14, 9:15 AM, Alexander Lisachenko wrote:
2014-11-05 17:02 GMT+03:00 Marco Pivetta <ocram...@gmail.com>:
For example, this alternative approach perfectly fits the current
doctrine/annotations use-case:
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;
[Entity::class => []]
[Table::class => ['name' => 'foo_table']]
class Foo
{
[Id::class => []]
[GeneratedValue::class => [GeneratedValue::UUID]]
[Column::class => ['name' => 'bar_column', 'type' => 'string']]
private $bar;
}
This looks great indeed for many reasons:
1) it's a simple array
2) it can be parsed with built-in DSL syntax for PHP, so any arbitrary
evaluations with constants can be applied transparently, e.g.
[Loggable::class => ['pointcut' => self::PREFIX . 'test' ]]
3) C# uses similar syntax with square brackets for annotations:
public class Foo
{
[Display(Name="Product Number")]
[Range(0, 5000)]
public int ProductID { get; set; }
}
However, I would like to see simple markers without nested associative
arrays, e.g just put single AnnotationName::class into brackets or specify
multiple annotations in one section:
[Entity::class, Table::class => 'foo_table']
class Foo
{
// ...
}
One other concern to think about:
In Drupal's case, we have a lot of class annotations. We use them for
discovery. That is, "find me all classes that are a Thingie, and
relevant metadata about them". (Where "is a Thingie" is more than just
"has this interface" in some cases.) The catch is we need the metadata
at very different times than we need the code itself; that's why we're
not just making it a method on the class.
One issue we ran into with the Doctrine parser was that it used
reflection to get the docblock to parse. That meant loading an awful
lot of code that was never actually used in that request, which had a
not-small performance impact.
In the end, we ended up modifying the parser to tokenize the file rather
than just loading it; that way we could free the memory used after each
file rather than holding it around forever, which had a huge memory
savings for us.
I don't know that's possible if done in the engine itself, nor if the
always-available opcode cache obviates that concern or to what degree; I
suppose I am more cautioning to be mindful of the impact of lots of
annotation use at scale, not just on CPU but on memory. There are
plenty of use cases for being interested in the annotations and NOT the
code itself, and we should make sure that's a supported use case that
won't blow up at large scale.
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php