Skip to content

Instantly share code, notes, and snippets.

@wakaba
Last active December 16, 2015 14:39
Show Gist options
  • Save wakaba/5450060 to your computer and use it in GitHub Desktop.
Save wakaba/5450060 to your computer and use it in GitHub Desktop.
sub define_in_lang_methods {
my ($class, %args) = @_;
my $copies = join "\n", map {
$_ . ' => $self->' . $_ . ',';
} @{$args{copied_columns} or []};
eval sprintf q{
sub %s::%s {
my $self = shift;
return $self->{_%s} ||= do {
my $texts = {};
%s->search(where => {%s => $self->%s})->each(sub {
$texts->{$_->lang} = $_;
});
return $texts;
};
}
push @{__PACKAGE__->__cached_methods}, '%s'
if __PACKAGE__->can('__cached_methods');
1;
},
$class,
$args{texts_method_name}, # sub %s
$args{texts_method_name},
$args{text_class_name}, # %s->search
$args{text_column_name}, # %s =>
$args{self_column_name}, # => $self->%s
$args{texts_method_name}, # __cached_methods
or die $@;
for my $column_name (@{$args{column_names}}) {
eval sprintf q{
# キャッシュは上位レイヤーで
sub %s::%s_in_lang {
my $self = shift;
my $lang = shift;
my $texts = $self->%s;
if (@_) {
return undef unless is_valid_hatena_short_lang_tag $lang;
$lang = normalize_hatena_text_lang $lang;
if ($texts->{$lang}) {
$texts->{$lang}->%s(shift);
} else {
my $st = %s->create(
%s => $self->%s,
%s => shift,
lang => $lang,
%s
);
$texts->{$lang} = $st;
}
return undef unless defined wantarray;
}
for my $l (@{+expand_lang_tags [$lang]}, keys %%$texts) {
if ($texts->{$l}) {
my $v = $texts->{$l}->%s;
return $v if defined $v and length $v;
}
}
return undef;
}
1;
},
$class,
$column_name, # sub %s_in_lang
$args{texts_method_name}, # $self->%s
$column_name, # ->%s()
$args{text_class_name}, # %s->create
$args{text_column_name}, # %s =>
$args{self_column_name}, # => $self->%s
$column_name, # %s => shift
$copies,
$column_name, # ->%s
or die $@;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment