Perl에서 $ 변수가 정의되어 있고 길이가 0이 아닌 문자열을 포함하는지 어떻게 간결하게 확인할 수 있습니까?
현재 다음 Perl을 사용하여 변수가 정의되어 있고 텍스트가 포함되어 있는지 확인합니다. defined
'초기화되지 않은 값'경고를 피하기 위해 먼저 확인 해야합니다.
if (defined $name && length $name > 0) {
# do something with $name
}
이것을 작성하는 더 나은 (아마 더 간결한) 방법이 있습니까?
정의 확인을 자주 볼 수 있으므로 undef 값 사용에 대한 경고를 처리 할 필요가 없습니다 (Perl 5.10에서는 문제가되는 변수를 알려줍니다).
Use of uninitialized value $name in ...
그래서이 경고를 피하기 위해 사람들은 온갖 종류의 코드를 생각해 내고 그 코드는 풍선 껌과 덕트 테이프가 아닌 솔루션의 중요한 부분처럼 보이기 시작합니다. 때로는 피하려는 경고를 명시 적으로 해제하여 수행중인 작업을 표시하는 것이 더 좋습니다.
{
no warnings 'uninitialized';
if( length $name ) {
...
}
}
다른 경우에는 데이터 대신 일종의 null 값을 사용하십시오. 함께 펄 5.10의 정의 또는 운영자는 , 당신이 줄 수있는 length
대신 경고를 트리거 할 변수의 명시 적 빈 문자열 (정의를 다시 제로 길이를 줄) :
use 5.010;
if( length( $name // '' ) ) {
...
}
Perl 5.12에서는 length
정의되지 않은 값에서도 undefined를 반환 하기 때문에 조금 더 쉽습니다 . 그것은 약간 어리석은 것처럼 보일지 모르지만 그것은 내가되고 싶었던 수학자를 기쁘게합니다. 그것은 경고를 발행하지 않으며, 이것이이 질문이 존재하는 이유입니다.
use 5.012;
use warnings;
my $name;
if( length $name ) { # no warning
...
}
mobrule에서 알 수 있듯이 약간의 절약을 위해 다음을 대신 사용할 수 있습니다.
if (defined $name && $name ne '') {
# do something with $name
}
정의 된 수표를 버리고 더 짧은 것을 얻을 수 있습니다. 예 :
if ($name ne '') {
# do something with $name
}
그러나 $name
정의되지 않은 경우 논리 흐름이 의도 한대로 작동하지만 사용중인 경우 warnings
(그리고 그래야만하는 경우) 다음과 같은 경고를 받게됩니다.
문자열 ne에서 초기화되지 않은 값 사용
따라서 $name
정의되지 않을 가능성이 있는 경우 해당 경고를 피하기 위해 무엇보다도 먼저 정의를 확인해야합니다. Sinan Ünür가 지적했듯이 Scalar :: MoreUtils 를 사용하면 다음과 같은 empty()
방법을 통해 바로 그 작업을 수행하는 코드 (정의성을 확인한 다음 길이가 0인지 확인)를 얻을 수 있습니다 .
use Scalar::MoreUtils qw(empty);
if(not empty($name)) {
# do something with $name
}
첫째, length
항상 음수가 아닌 숫자를 반환하므로
if ( length $name )
과
if ( length $name > 0 )
동등합니다.
정의되지 않은 값을 빈 문자열로 대체해도 괜찮다 //=
면 LHS가 정의되지 않은 한 RHS를 LHS에 할당하는 Perl 5.10 연산자를 사용할 수 있습니다 .
#!/usr/bin/perl
use feature qw( say );
use strict; use warnings;
my $name;
say 'nonempty' if length($name //= '');
say "'$name'";
$name
정의되지 않은 경우 빈 문자열이 할당되므로 초기화되지 않은 변수에 대한 경고 가 없습니다.
그러나 5.10 설치에 의존하지 않으려면 Scalar :: MoreUtils에서 제공하는 기능을 사용하십시오 . 예를 들어, 위의 내용은 다음과 같이 작성할 수 있습니다.
#!/usr/bin/perl
use strict; use warnings;
use Scalar::MoreUtils qw( define );
my $name;
print "nonempty\n" if length($name = define $name);
print "'$name'\n";
당신은 소지품하지 않을 경우 $name
, 사용 default
.
변수가 undef
같거나 같은지 상관하지 않는 경우 ''
일반적으로 다음과 같이 요약합니다.
$name = "" unless defined $name;
if($name ne '') {
# do something with $name
}
넌 말할 수있다
$name ne ""
대신에
length $name > 0
단순하고 우아한 방식으로 반복적 인 작업을 수행하는 것이 항상 가능한 것은 아닙니다.
Just do what you always do when you have common code that gets replicated across many projects:
Search CPAN, someone may have already the code for you. For this issue I found Scalar::MoreUtils.
If you don't find something you like on CPAN, make a module and put the code in a subroutine:
package My::String::Util;
use strict;
use warnings;
our @ISA = qw( Exporter );
our @EXPORT = ();
our @EXPORT_OK = qw( is_nonempty);
use Carp qw(croak);
sub is_nonempty ($) {
croak "is_nonempty() requires an argument"
unless @_ == 1;
no warnings 'uninitialized';
return( defined $_[0] and length $_[0] != 0 );
}
1;
=head1 BOILERPLATE POD
blah blah blah
=head3 is_nonempty
Returns true if the argument is defined and has non-zero length.
More boilerplate POD.
=cut
Then in your code call it:
use My::String::Util qw( is_nonempty );
if ( is_nonempty $name ) {
# do something with $name
}
Or if you object to prototypes and don't object to the extra parens, skip the prototype in the module, and call it like: is_nonempty($name)
.
The excellent library Type::Tiny provides an framework with which to build type-checking into your Perl code. What I show here is only the thinnest tip of the iceberg and is using Type::Tiny in the most simplistic and manual way.
Be sure to check out the Type::Tiny::Manual for more information.
use Types::Common::String qw< NonEmptyStr >;
if ( NonEmptyStr->check($name) ) {
# Do something here.
}
NonEmptyStr->($name); # Throw an exception if validation fails
How about
if (length ($name || '')) {
# do something with $name
}
This isn't quite equivalent to your original version, as it will also return false if $name
is the numeric value 0 or the string '0'
, but will behave the same in all other cases.
In perl 5.10 (or later), the appropriate approach would be to use the defined-or operator instead:
use feature ':5.10';
if (length ($name // '')) {
# do something with $name
}
This will decide what to get the length of based on whether $name
is defined, rather than whether it's true, so 0/'0'
will handle those cases correctly, but it requires a more recent version of perl than many people have available.
if ($name ) { #since undef and '' both evaluate to false #this should work only when string is defined and non-empty... #unless you're expecting someting like $name="0" which is false. #notice though that $name="00" is not false }
'Program Tip' 카테고리의 다른 글
Node.JS의 구조 해제 (0) | 2020.10.19 |
---|---|
요소의 모든 자식에 스타일을 적용하려면 어떻게합니까 (0) | 2020.10.19 |
공유 라이브러리에서 해결되지 않은 기호를 쉽게 확인 하시겠습니까? (0) | 2020.10.19 |
왜 "메서드 오버로딩을 피해야합니까?" (0) | 2020.10.19 |
다른 국가에서 웹 기반 Google Play를 탐색하는 방법은 무엇입니까? (0) | 2020.10.19 |