use Data::Munge;
use overload
- '""' => 'escaped_string',
- '.' => 'dot',
- '.=' => 'dot_equals',
- '=' => 'clone',
+ '""' => '_hsv_escaped_string',
+ '.' => '_hsv_dot',
+ 'bool' => '_hsv_is_true',
fallback => 1,
;
sub new {
+ if (ref($_[0])) { my $c = shift; return $c->_hsv_unescaped_string->new(@_) }
my ($class, @raw_parts) = @_;
+ my $opts = (ref($raw_parts[-1]) eq 'HASH') ? pop(@raw_parts) : {};
+
my @parts = map {
if (ref($_) eq 'ARRAY') {
$_
}
} @raw_parts;
- my $self = bless { parts => \@parts }, $class;
+ my $self = bless { parts => \@parts, %$opts }, $class;
return $self;
}
-sub escaped_string {
+sub AUTOLOAD {
+ my $invocant = shift;
+ (my $meth = our $AUTOLOAD) =~ s/.*:://;
+ die "No such method ${meth} on ${invocant}"
+ unless ref($invocant);
+ return $invocant->_hsv_unescaped_string->$meth(@_);
+}
+
+sub _hsv_escaped_string {
my $self = shift;
+ if ($self->{ignore}{scalar caller}) {
+ return $self->_hsv_unescaped_string;
+ }
+
return join '', map +(
$_->[1]
? byval {
), @{$self->{parts}};
}
-sub unescaped_string {
+sub _hsv_unescaped_string {
my $self = shift;
return join '', map $_->[0], @{$self->{parts}};
}
-sub dot {
+sub _hsv_dot {
my ($self, $str, $prefix) = @_;
return $self unless $str;
push @parts, @new_parts;
}
- return ref($self)->new(@parts);
-}
-
-sub dot_equals {
- my ($self, $str, $prefix) = @_;
-
- return $self unless $str;
-
- my @new_parts = (
- $str->$_isa(__PACKAGE__)
- ? @{$str->{parts}}
- : [ $str, 1 ]
- );
-
- push @{$self->{parts}}, @new_parts;
-
- return $self;
+ return ref($self)->new(@parts, { ignore => $self->{ignore} });
}
-sub clone {
- my $self = shift;
-
- return ref($self)->new(@{$self->{parts}});
+sub _hsv_is_true {
+ my ($self) = @_;
+ return 1 if grep length($_), map $_->[0], @{$self->{parts}};
}
sub ref { '' }
+sub DESTROY { }
+
1;