我正在尝试简化我的Imports System.Runtime.InteropServices
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
SetCueText(TextBox1, "Enter Name here")
End Sub
End Class
Public Module CueBannerText
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As Int32
End Function
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
Private Const EM_SETCUEBANNER As Integer = &H1501
Public Sub SetCueText(cntrl As Control, text As String)
If TypeOf cntrl Is ComboBox Then
Dim Edit_hWnd As IntPtr = FindWindowEx(cntrl.Handle, IntPtr.Zero, "Edit", Nothing)
If Not Edit_hWnd = IntPtr.Zero Then
SendMessage(Edit_hWnd, EM_SETCUEBANNER, 0, text)
End If
ElseIf TypeOf cntrl Is TextBox Then
SendMessage(cntrl.Handle, EM_SETCUEBANNER, 0, text)
End If
End Sub
End Module
类的一类属性的定义。例如,考虑一类可以标记为Moose
的属性,这里是一个这样的属性的示例:
private
想象一下,类package MyPkg;
use Moose;
has some_attribute => (
is => 'ro',
isa => 'Str',
lazy => 1,
init_arg => undef, # prevent from being set by constructor
builder => "_set_some_attribute"
);
sub _set_some_attribute {
my ( $self ) = @_;
return "value_of_some_attribute";
}
sub some_method_that_uses_some_attribute {
my ( $self ) = @_;
return "The value of some attribute: " . $self->some_attribute;
}
package main;
use feature qw(say);
use strict;
use warnings;
my $o = MyPkg->new();
say $o->some_method_that_uses_some_attribute;
的属性some_attribute
属于一组可以标记为MyPkg
的属性,其中所有属性类型为private
的属性都是private
并且不能由构造函数设置。也就是说,我想简化:
lazy
这样的事情
package MyPkg;
use Moose;
has some_attribute => (
is => 'ro',
isa => 'Str',
lazy => 1,
init_arg => undef, # prevent from being set by constructor
builder => "_set_some_attribute"
);
这可以用package MyPkg;
use Moose;
use MyMooseAttributeExtensions; # <-- some Moose extension that I have to write
has some_attribute => (is => 'ro', isa => 'Str', private => 1 );
吗?
答案 0 :(得分:4)
如果您有许多仅按名称不同的属性,则可以 立即声明它们:
package Point; use Moose; has [ 'x', 'y' ] => ( is => 'ro', isa => 'Int' );
另外,因为
has
只是一个函数调用,所以你可以在循环中调用它:for my $name ( qw( x y ) ) { my $builder = '_build_' . $name; has $name => ( is => 'ro', isa => 'Int', builder => $builder ); }
还有lazy_build
属性,请参阅Moose::Meta::Attribute
,但文档说明:&#34;请注意,强烈建议不要使用此功能&#34; < / p>
最后一个选项是使用扩展包。
我想这已经存在于CPAN的某个地方了,但我找不到了,所以这是我尝试实现Moose
扩展名:
package MyMooseAttributeExtensions;
use strict;
use warnings;
our %orig_has; # save original 'has' sub routines here
sub import {
my $callpkg = caller 0;
{
no strict 'refs';
no warnings 'redefine';
$orig_has{$callpkg} = *{$callpkg."::has"}{CODE};
*{$callpkg."::has"} = \&private_has;
}
return;
}
sub private_has {
my ($attr, %args) = @_;
my $callpkg = caller 0;
if (exists $args{private} ) {
delete $args{private};
%args = (
%args,
lazy => 1,
init_arg => undef, # prevent from being set by constructor
builder => "_set_$attr"
);
}
$orig_has{$callpkg}->($attr, %args);
}
1;