📜 ⬆️ ⬇️

Meta-Object Protocol in Perl6

In some programming languages, there is an interface for creating a class not through its definition, but through the execution of some code. This API is called Meta-Object Protocol or MOP.

In Perl 6, there is a MOP that allows you to create classes, roles, and grammars, add methods and attributes, and do class introspection. For example, here’s how you can use MOP calls in Rakudo to find out how the type Rat (rational numbers) is implemented. Calls to MOP methods usually begin with a point rather than a period. ^

$ perl6 > say join ', ', Rat.^attributes $!numerator, $!denominator > #     , > #       > say join ', ', Rat.^methods(:local).pick(5) unpolar, ceiling, reals, Str, round > say Rat.^methods(:local).grep('log').[0].signature.perl :(Numeric $x: Numeric $base = { ... };; *%_) 

')
Most strings should be clear: objects of class Rat have two attributes, $! Numerator and $! Denominator, and many methods. The log method takes a Numeric value as the caller (it is marked with a colon after the parameter name) and the optional second parameter $ base, which has a default value (Euler number e).

A good example of use can be taken from the Perl 6 database interface. It has the ability to record object calls to a log, while limiting the recording of methods to one specific role (for example, only the role that deals with connecting to the database, or data retrieval) . Here is an example:

  sub log-calls($obj, Role $r) { my $wrapper = RoleHOW.new; for $r.^methods -> $m { $wrapper.^add_method($m.name, method (|$c) { #    # note()   standard error note ">> $m"; #         #    nextsame; }); } $wrapper.^compose(); #  'does'   ,  'but',  #     $obj does $wrapper; } role Greet { method greet($x) { say "hello, $x"; } } class SomeGreeter does Greet { method LOLGREET($x) { say "OH HAI "~ uc $x; } } my $o = log-calls(SomeGreeter.new, Greet); #   log,     Greet $o.greet('you'); #    log,      $o.LOLGREET('u'); 


Displays:

  >> greet hello, you OH HAI U 


Using Meta-Object Protocol, classes, roles and grammars are available to you not only through a special syntax, but also through a regular API. This adds flexibility to the OOP code and allows introspection and modification of objects.

Source: https://habr.com/ru/post/265199/


All Articles