Yahoo! search interface: Difference between revisions

→‎{{header|Tcl}}: Corrections and improvements
(→‎{{header|Tcl}}: Corrections and improvements)
Line 235:
}
 
# Ugly; uses global state variable but works with all current Tcl versions
proc Nextpage {term} {
incr ::page
Line 241 ⟶ 242:
 
# Usage: get the first two pages of results
set ::page 1
set term "test"
foreach result_set [list [YahooSearch $term] [Nextpage $term]] {
Line 248 ⟶ 249:
}
}</lang>
{{works with|Tcl|8.6}}
Tcl 8.6 can use its coroutine support to produce an iterator more like that Python code:
With Tcl 8.6, more options are available for managing the global state, through objects and coroutines. First, an object-based solution that takes the basic <tt>YahooSearch</tt> functionality and dresses it up to be more Tcl-like:
<lang tcl>proc yahoo! term {
<lang tcl>package require Tcl 8.6
 
oo::class create WebSearcher {
variable page term results
constructor searchTerm {
set page 0
set term $searchTerm
my nextPage
}
# This next method *is* a very Tcl-ish way of doing iteration.
method for {titleVar contentsVar urlVar body} {
upvar 1 $titleVar t $contentsVar c $urlVar v
foreach {t c v} $results {
uplevel 1 $body
}
}
# Reuse the previous code for simplicity rather than writing it anew
# Of course, if we were serious about this, we'd put the code here properly
method nextPage {} {
set results [YahooSearch $term [incr page]]
return
}
}
 
# How to use. Note the 'foreach' method use below; new "keywords" as methods!
set ytest [WebSearcher new "test"]
$ytest for title - url {
puts "\"$title\" : $url"
}
$ytest nextPage
$ytest for title - url {
puts "\"$title\" : $url"
}
$ytest delete ;# standard method that deletes the object</lang>
However, the paradigm of an iterator is also interesting and is more appropriately supported through a coroutine. This version conceals the fact that the service produces output in pages; care should be taken with it because it can produce rather a lot of network traffic...
<lang tcl>package require Tcl 8.6
 
<lang tcl>proc yahoo! term {
coroutine yahoo![incr ::yahoo] apply {term {
yield [info coroutine]
Line 264 ⟶ 303:
}
 
# test by getting first fifty titles...
set it [yahoo! "test"]
for {set i 50} {$i>0} {incr i -1} {
while 1 {
puts [dict get [$it] title]
after 300 ;# Slow the code down... :-)
Anonymous user