如何查看一个CLOS类是否是另一个CLOS类的子类?
你知道如何驼鹿自动打开strict和warnings导入过程中?我希望通过启用autodie和use feature ':5.10'在我的Moose类中扩展该行为.
我已经跟踪了Moose在这里做的事情,Moose::Exporter其中组装了importMoose的一个自定义子组件,用于调用strict->import和warnings->import调用类.
但是,我无法找到一种以Moose-ish方式扩展此导入方法的方法.
我该怎么处理?
如果您创建一个类:
class Foo { }
Run Code Online (Sandbox Code Playgroud)
该类将继承其所有方法Any,然后Mu.
我想创建一个不从任何其他类继承的类:它应该包含一个FALLBACK方法,该方法应该捕获对该对象实例的所有方法调用.
我查看了MetaModel代码,但似乎没有一种简单的方法来实现这一目标.欢迎所有建议!
更新:我决定采用Jonathan Worthington所描述的拦截任何方法调用方式.这导致CPAN上有两个新的Perl 6模块:InterceptAllMethods和Object :: Trampoline.
我即将选择用于新项目的语言:Perl5或Perl6.到目前为止6胜,只是它缺少了Moo懒惰的属性.我在模块中找到的两个实现缺少关键功能.因此,我尝试编写自己的实现.
我遇到的第一个问题是.package在角色中声明的属性的内容.考虑以下内容:
role HOW1 {
method compose ( Mu $class ) {
note "HOW1.compose";
nextsame;
}
}
role HOW2 {
method compose ( Mu $class ) {
note "HOW2.compose";
nextsame;
}
}
multi trait_mod:<is> (Attribute:D $attr, :$mooish!) {
note "Attribute's package.HOW: ", $attr.package.HOW;
note '$*PACKAGE.HOW: ', $*PACKAGE.HOW;
$attr.package.HOW does HOW1;
$*PACKAGE.HOW does HOW2;
}
class Foo {
has $.bar is mooish;
}
role FooRole {
has $.baz is mooish;
}
Run Code Online (Sandbox Code Playgroud)
脚本的输出如下:
Attribute's package.HOW: Perl6::Metamodel::ClassHOW.new
$*PACKAGE.HOW: …Run Code Online (Sandbox Code Playgroud) 这与类的问题类似,但相同的过程似乎不适用于语法。
grammar TestGrammar {
token num { \d+ }
}
my $test-grammar = TestGrammar.new();
my $token = $test-grammar.^lookup('num');
say "3" ~~ $token;
Run Code Online (Sandbox Code Playgroud)
这将返回:
Type check failed in binding to parameter '<anon>'; expected TestGrammar but got Match (Match.new(:orig("3")...)
in regex num at pointer-to-token.raku line 2
in block <unit> at pointer-to-token.raku line 9
Run Code Online (Sandbox Code Playgroud)
这似乎表明您需要绑定到类/语法,而不是“裸”令牌。但是,尚不清楚如何做到这一点。将语法或其实例作为参数传递会返回不同的错误:
Cannot look up attributes in a TestGrammar type object. Did you forget a '.new'?
Run Code Online (Sandbox Code Playgroud)
知道为什么这实际上不起作用吗?
更新:按照上述问题中引用的^find_method方式使用也不起作用。同样的问题。使用也不能解决问题。assuming
更新 2:我似乎有所进展:
my $token = …Run Code Online (Sandbox Code Playgroud) 在Perl5和Moose中,线性isa或线性化isa有助于理解类层次结构.
WHAT方法显示了值的具体类型:
> 42.WHAT
(Int)
Run Code Online (Sandbox Code Playgroud)
我该如何表现出类似的东西
> 42.hypothetical-type-hierarchy
(Int) ? is (Cool) ? is (Any) ? is (Mu)
? does (Real) ? does (Numeric)
Run Code Online (Sandbox Code Playgroud)
...可能还有每个消费角色的更多行?
编辑:具有两个角色的示例
class Beta {}
role Delta {}
role Gamma does Delta {}
role Eta {}
role Zeta does Eta {}
role Epsilon does Zeta {}
class Alpha is Beta does Gamma does Epsilon {}
# (Alpha) ? is (Beta)
# ? does (Gamma) ? does (Delta)
# ? does (Epsilon) …Run Code Online (Sandbox Code Playgroud) 问候,
我正在学习Moose,而我正在尝试用Moose 编写一个CGI :: Application子类,由于CGI-App不是基于Moose而变得困难.
在我的其他CGI-App子类中,我喜欢让父类使用一个setup方法来查看子类的符号表并自动设置runmodes.我想我可以使用Moose的元类设施以更清洁的方式实现同样的目的.所以这是我在父类中的内容:
use MooseX::Declare;
class MyApp::CGI
extends Moose::Object
extends CGI::Application {
method setup {
$self->start_mode( 'main' );
my @methods = map { $_->name } $self->meta->get_all_methods;
$self->run_modes( map { /^rm_(.+)$/ => $_ }
grep { /^rm_/ }
@methods
);
}
}
Run Code Online (Sandbox Code Playgroud)
......在我的孩子班上:
use MooseX::Declare;
class MyApp::CGI::Login
extends MyApp::CGI {
method rm_main {
return "it works";
}
}
Run Code Online (Sandbox Code Playgroud)
我意识到我的runmodes没有正确设置的原因是因为setupCGI-App构造函数调用了Moose::Object它,并且在我的类中坚持自己的构造函数.我尝试用方法修饰符解决这个问题:
around new {
$self = $orig->( @_ );
$self->CGI::Application::new( …Run Code Online (Sandbox Code Playgroud) 我正在使用common-lisp进行实时图形实验,到目前为止它已经很棒了.我对速度的要求和与cffi的轻松兼容意味着我正在使用'typed'数组.代码中真正令人感到难看的一个区域是我的矩阵和矢量数学函数的泛型版本.由于CLOS无法专注于数组的长度,我正在做这样的事情:
(defun v+ (vec-a vec-b)
(%v+ vec-a vec-b (length a) (length b)))
(defmethod %v+ (va vb (la (eql 3)) (lb (eql 3)))
***CODE HERE***)
Run Code Online (Sandbox Code Playgroud)
这有效,但感觉不对.我已经看到了各种CL实现的扩展,并听说了MOP的承诺.
我已经避开了这个,因为我担心它会破坏一些CL实现的功能,但我最近看到了Closer-to-Mop项目.
核心问题: MOP是否提供了一种更有效的长度专业化方法?我应该关注哪些领域/技术?
这显然是不可能的……
role Versioned {
method version () {
return self.^api;
}
}
class WithApi:ver<0.0.1>:auth<github:JJ>:api<0> does Versioned {}
class WithApi:ver<0.0.1>:auth<github:JJ>:api<1> does Versioned {}
say WithApi:api<0>.new.version;
say WithApi:api<1>.new.version;
Run Code Online (Sandbox Code Playgroud)
这与
==SORRY!=== Error while compiling /home/jmerelo/progs/perl6/my-perl6-examples/api-versioned.p6
Redeclaration of symbol 'WithApi'
at /home/jmerelo/progs/perl6/my-perl6-examples/api-versioned.p6:11
------> 1>:auth<github:JJ>:api<1> does Versioned? {}
Run Code Online (Sandbox Code Playgroud)
那么甚至有可能在单个程序中use使用不同的apis、相同的名称吗?
更新:如果它们包含在不同的文件中,这是获得的错误:
P6M Merging GLOBAL symbols failed: duplicate definition of symbol WrongType
Run Code Online (Sandbox Code Playgroud)