Method: WordNet::Synset#traverse

Defined in:
lib/wordnet/synset.rb

#traverse(type, &block) ⇒ Object

With a block, yield a WordNet::Synset related to the receiver via a link of the specified type, recursing depth first into each of its links if the link type is recursive. To exit from the traversal at any depth, throw :stop_traversal.

If no block is given, return an Enumerator that will do the same thing instead.

# Print all the parts of a boot
puts lexicon[:boot].traverse( :member_meronyms ).to_a

You can also traverse with an addiitional argument that indicates the depth of recursion by calling #with_depth on the Enumerator:

$lex[:fencing].traverse( :hypernyms ).with_depth.each {|ss,d| puts "%02d: %s" % [d,ss] }
# (outputs:)

01: play, swordplay (noun): [noun.act] the act using a sword (or other weapon) vigorously
  and skillfully (hypernym: 1, hyponym: 1)
02: action (noun): [noun.act] something done (usually as opposed to something said)
  (hypernym: 1, hyponym: 33)
03: act, deed, human action, human activity (noun): [noun.tops] something that people do
  or cause to happen (hypernym: 1, hyponym: 40)
...


625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
# File 'lib/wordnet/synset.rb', line 625

def traverse( type, &block )
  enum = Enumerator.new do |yielder|
    traversals = [ self.semanticlink_enum(type) ]
    syn        = nil
    typekey    = SEMANTIC_TYPEKEYS[ type ]
    recurses   = self.class.linktypes[ typekey ][:recurses]

    self.log.debug "Traversing %s semlinks%s" % [ type, recurses ? " (recursive)" : ''  ]

    catch( :stop_traversal ) do
      until traversals.empty?
        begin
          self.log.debug "  %d traversal/s left" % [ traversals.length ]
          syn = traversals.last.next

          if enum.with_depth?
            yielder.yield( syn, traversals.length )
          else
            yielder.yield( syn )
          end

          traversals << syn.semanticlink_enum( type ) if recurses
        rescue StopIteration
          traversals.pop
        end
      end
    end
  end

  def enum.with_depth?
    @with_depth = false if !defined?( @with_depth )
    return @with_depth
  end

  def enum.with_depth
    @with_depth = true
    self
  end

  return enum.each( &block ) if block
  return enum
end