他の答えは、私がチュートリアルの投稿に書いたことを説明しているようです。つまり、Mojo :: DOM(実際にはMojo :: Collectionクラス)の別の便利なメソッドである、を理解するようになったということを付け加えたいと思いますpluck
。この方法は、視覚的な複雑さを軽減します
->map(sub{$_->text})
に
->pluck('text')
さらに、少なくともいくつかのeach
呼び出しが無関係であり、リストコンテキストで使用されるMojo::Collectionが「DoWhatIMean」でeach
自動的に実行されることに気付きました。
編集:私はこれをチェックしました、そして実際に文字列として使われるとき、要素は改行で結合されます。これは私が望んでいることではないので、私はeach
電話を返しました。
ここで述べているのは、同じチュートリアルスクリプトを今すぐ作成する方法です。
#!/usr/bin/env perl
use strict;
use warnings;
use 5.10.0;
use Mojo::DOM;
my $dom = Mojo::DOM->new(<<'HTML');
<div class="box notranslate" id="venueHours">
<h5 class="translate">Hours</h5>
<div class="status closed">Currently closed</div>
<div class="hours">
<div class="timespan">
<div class="openTime">
<div class="days">Mon,Tue,Wed,Thu,Sat</div>
<span class="hours"> 10:00 AM–6:00 PM</span>
</div>
</div>
<div class="timespan">
<div class="openTime">
<div class="days">Fri</div>
<span class="hours"> 10:00 AM–9:00 PM</span></div>
</div>
<div class="timespan">
<div class="openTime">
<div class="days">Sun</div>
<span class="hours"> 10:00 AM–5:00 PM</span>
</div>
</div>
</div>
</div>
HTML
say "div days:";
say for $dom->find('div.days')->pluck('text')->each;
say "\nspan hours:";
say for $dom->find('span.hours')->pluck('text')->each;
say "\nOpen Times:";
say for $dom->find('div.openTime')
->map(sub{$_->children->each})
->pluck('text')
->each;
メソッドがMojo::Collectionオブジェクトを返す->pluck('children')
ため、使用しないことに注意してください。つまり、からの戻り値はコレクションのコレクションになります。構造をフラット化するために、呼び出しの結果を呼び出す必要があるため、その特定の呼び出しを削除することはできません。children
pluck
each
children
->map
しかし、今、私はこの面倒を一緒に避けられなかったのだろうか?Mojo :: DOMはCSS3セレクター(w3schoolsリファレンス)を優れた方法でサポートしています。親(div.openTime
)を直接選択するのではなく、セレクターでその子を選択することをお勧めします。
say "\nOpen Times:";
say for $dom->find('div.openTime > *')->pluck('text')->each;
したがって、ここには良い教訓があります。セレクターが必要なコレクションに近いものを提供できるようにすることで、後で変換する必要がなくなります。
最後の質問に答えるには:
これを翻訳するには
say for $dom->find('div.openTime')
->map(sub{$_->children->each})
->map(sub{$_->text})
->each;
もっとC風のPerlに(私はそれをfor(i=0;i<10;i++){ ... }
極端にとらえませんが)それは次のように見えるかもしれません
my @open_times = $dom->find('div.openTime')->each;
my @all_children;
foreach my $elem ( @open_times ) {
my @children = $elem->children->each;
push @all_children, @children;
}
my @texts;
foreach my $child ( @all_children ) {
push @texts, $child->text;
}
foreach my $text ( @texts ) {
print $text . "\n";
}
私がMojo(オブジェクトチェーン)の方法を好む理由がわかると思います。
2番目の質問について:Mojoliciousには、優れた(場合によっては過剰な)ドキュメントがあります。システム全体について学ぶためにここから始めてください。特にMojo::DOMとMojo::Collectionについて読むと、 DOMの解析を処理するのに十分なはずです。問題の一部は、DOMオブジェクトとCollectionオブジェクトの相互依存性に気づかなかったため、すべてのメソッド呼び出しがDOMオブジェクトに対して行われたと誤って想定したことだと思います。注意深く読むと、いくつかのDOMメソッド(返されるものは複数の結果を返す可能性があります)がCollectionオブジェクトを返すことがわかります。これfind
は、そのようなメソッドの1つです。