Module: Linguistics

Defined in:
lib/linguistics.rb,
lib/linguistics/iso639.rb,
lib/linguistics/en/wordnet.rb

Overview

This file contains functions for finding relations for English words. It requires the Ruby-WordNet module to be installed; if it is not installed, calling the functions defined by this file will raise NotImplemented exceptions if called. Requiring this file adds functions and constants to the Linguistics::EN module.

Synopsis

# Test to be sure the WordNet module loaded okay.
Linguistics::EN.has_wordnet?
# => true

# Fetch the default synset for the word "balance"
"balance".synset
# => #<WordNet::Synset:0x40376844 balance (noun): "a state of equilibrium"
 (derivations: 3, antonyms: 1, hypernyms: 1, hyponyms: 3)>

# Fetch the synset for the first verb sense of "balance"
"balance".en.synset( :verb )
# => #<WordNet::Synset:0x4033f448 balance, equilibrate, equilibrize, equilibrise
(verb): "bring into balance or equilibrium; "She has to balance work and her
domestic duties"; "balance the two weights"" (derivations: 7, antonyms: 1,
verbGroups: 2, hypernyms: 1, hyponyms: 5)>

# Fetch the second noun sense
"balance".en.synset( 2, :noun )
# => #<WordNet::Synset:0x404ebb24 balance (noun): "a scale for weighing; depends
on pull of gravity" (hypernyms: 1, hyponyms: 5)>

# Fetch the second noun sense's hypernyms (more-general words, like a superclass)
"balance".en.synset( 2, :noun ).hypernyms
# => [#<WordNet::Synset:0x404e5620 scale, weighing machine (noun): "a measuring
instrument for weighing; shows amount of mass" (derivations: 2, hypernyms: 1,
hyponyms: 2)>]

# A simpler way of doing the same thing:
"balance".en.hypernyms( 2, :noun )
# => [#<WordNet::Synset:0x404e5620 scale, weighing machine (noun): "a measuring
instrument for weighing; shows amount of mass" (derivations: 2, hypernyms: 1,
hyponyms: 2)>]

# Fetch the first hypernym's hypernyms
"balance".en.synset( 2, :noun ).hypernyms.first.hypernyms
# => [#<WordNet::Synset:0x404c60b8 measuring instrument, measuring system,
measuring device (noun): "instrument that shows the extent or amount or quantity
or degree of something" (hypernyms: 1, hyponyms: 83)>]

# Find the synset to which both the second noun sense of "balance" and the
# default sense of "shovel" belong.
("balance".en.synset( 2, :noun ) | "shovel".en.synset)
# => #<WordNet::Synset:0x40473da4 instrumentality, instrumentation (noun): "an
artifact (or system of artifacts) that is instrumental in accomplishing some
end" (derivations: 1, hypernyms: 1, hyponyms: 13)>

# Fetch just the words for the other kinds of "instruments"
"instrument".en.hyponyms.collect {|synset| synset.words}.flatten
# => ["analyzer", "analyser", "cautery", "cauterant", "drafting instrument",
"extractor", "instrument of execution", "instrument of punishment", "measuring
instrument", "measuring system", "measuring device", "medical instrument",
"navigational instrument", "optical instrument", "plotter", "scientific
instrument", "sonograph", "surveying instrument", "surveyor's instrument",
"tracer", "weapon", "arm", "weapon system", "whip"]

Authors

Copyright © 2003 The FaerieMUD Consortium. All rights reserved.

This module is free software. You may use, modify, and/or redistribute this software under the terms of the Perl Artistic License. (See language.perl.com/misc/Artistic.html)

Version

$Id: wordnet.rb,v 1.3 2003/09/14 11:28:02 deveiant Exp $

Defined Under Namespace

Modules: EN Classes: LanguageProxyClass

Constant Summary collapse

SVNRev =

Subversion revision

%q$Rev: 78 $
SVNid =

Subversion ID

%q$Id: linguistics.rb 78 2005-07-13 19:58:43Z ged $
DefaultLanguages =

Language module implementors should do something like:

Linguistics::DefaultLanguages.push( :ja ) # or whatever

so that direct requiring of a language module sets the default.

[]
DefaultExtClasses =

The list of Classes to add linguistic behaviours to.

[String, Numeric, Array]
LanguageCodes =

Hash of ISO639 2- and 3-letter language codes

{}

Class Method Summary collapse

Class Method Details

.classical=(val) ⇒ Object

Set the ‘classical pluralizations’ flag to val. Setting is local to calling thread.



318
319
320
# File 'lib/linguistics.rb', line 318

def classical=( val )
	Thread.current[:classical_plurals] = val
end

.classical?Boolean

Return the value of the ‘classical pluralizations’ flag. Setting is local to calling thread.

Returns:

  • (Boolean)


324
325
326
# File 'lib/linguistics.rb', line 324

def classical?
	Thread.current[:classical_plurals] ? true : false
end

.extend_object(obj) ⇒ Object

Extend the specified target object with one or more language proxy methods, each of which provides access to one or more linguistic methods for that language.



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/linguistics.rb', line 118

def self::extend_object( obj )
	case obj
	when Class
		# $stderr.puts "Extending %p" % obj if $DEBUG
		self::installLanguageProxy( obj )
	else
		sclass = (class << obj; self; end)
		# $stderr.puts "Extending a object's metaclass: %p" % obj if $DEBUG
		self::installLanguageProxy( sclass )
	end

	super
end

.included(mod) ⇒ Object

Extend the including class with linguistics proxy methods.



134
135
136
137
# File 'lib/linguistics.rb', line 134

def self::included( mod )
	# $stderr.puts "Including Linguistics in %p" % mod if $DEBUG
	mod.extend( self ) unless mod == Linguistics
end

.installDelegatorProxy(klass, langcode) ⇒ Object

Install a regular proxy method in the given klass that will delegate calls to missing method to the languageProxy for the given language.



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/linguistics.rb', line 196

def self::installDelegatorProxy( klass, langcode )

	# Alias any currently-extant
	if klass.instance_methods( false ).include?( "method_missing" )
		klass.module_eval %{
			alias_method :__orig_method_missing, :method_missing
		}
	end

	# Add the #method_missing method that auto-installs delegator methods
	# for methods supported by the linguistic proxy objects.
	klass.module_eval {
		define_method( :method_missing ) do |sym, *args|

			if self.send( langcode ).respond_to?( sym )

				# $stderr.puts "Installing linguistic delegator method #{sym} " \
				#	"for the '#{langcode}' proxy"
				self.class.module_eval %{
					def #{sym}( *args )
						self.#{langcode}.#{sym}( *args )
					end
				}
				self.method( sym ).call( *args )

			# Otherwise either call the overridden proxy method if there is
			# one, or just let our parent deal with it.
			else
				if self.respond_to?( :__orig_method_missing )
					return self.__orig_method_missing( sym, *args )
				else
					super( sym, *args )
				end
			end
		end
	}
end

.installLanguageProxy(klass, languages = DefaultLanguages) ⇒ Object

Install the language proxy



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/linguistics.rb', line 151

def self::installLanguageProxy( klass, languages=DefaultLanguages )
	languages.replace( DefaultLanguages ) if languages.empty?

	# Create an languageProxy class for each language specified
	languages.each {|lang|
		# $stderr.puts "Extending the %p class with %p" %
		#	[ klass, lang ] if $DEBUG

		# Load the language module (skipping to the next if it's already
		# loaded), make an languageProxy class that delegates to it, and figure
		# out what the languageProxy method will be called.
		mod = loadLanguage( lang.to_s.downcase )
		ifaceMeth = mod.name.downcase.sub( /.*:/, '' )
		languageProxyClass = makeLanguageProxy( mod )

		# Install a hash for languageProxy classes and an accessor for the
		# hash if it's not already present.
		if !klass.class_variables.include?( "@@__languageProxy_class" )
			klass.module_eval %{
				@@__languageProxy_class = {}
				def self::__languageProxy_class; @@__languageProxy_class; end
			}, __FILE__, __LINE__
		end

		# Merge the current languageProxy into the hash
		klass.__languageProxy_class.merge!( ifaceMeth => languageProxyClass )

		# Set the language-code proxy method for the class unless it has one
		# already
		unless klass.instance_methods(true).include?( ifaceMeth )
			klass.module_eval %{
				def #{ifaceMeth}
					@__#{ifaceMeth}_languageProxy ||=
						self.class.__languageProxy_class["#{ifaceMeth}"].
						new( self )
				end
			}, __FILE__, __LINE__
		end
	}
end

.makeLanguageProxy(mod) ⇒ Object

Make an languageProxy class that encapsulates all of the inflect operations using the given language module.



142
143
144
145
146
147
# File 'lib/linguistics.rb', line 142

def self::makeLanguageProxy( mod )
	# $stderr.puts "Making language proxy for mod %p" % [mod]
	Class::new( LanguageProxyClass ) {
		@langmod = mod
	}
end

.numObject Also known as: NUM

Get the default count for all unspecified plurals. Setting is local to calling thread.



310
311
312
# File 'lib/linguistics.rb', line 310

def num
	Thread.current[:persistent_count]
end

.num=(val) ⇒ Object Also known as: NUM=

Set the default count for all unspecified plurals to val. Setting is local to calling thread.



303
304
305
# File 'lib/linguistics.rb', line 303

def num=( val )
	Thread.current[:persistent_count] = val
end

.use(*languages) ⇒ Object

Add linguistics functions for the specified languages to Ruby’s core classes. The interface to all linguistic functions for a given language is through a method which is the same the language’s international 2- or 3-letter code (ISO 639). You can also specify a Hash of configuration options which control which classes are extended:

:classes

Specify the classes which are to be extended. If this is not specified, the Class objects in Linguistics::DefaultExtClasses (an Array) are extended.

:installProxy

Install a proxy method in each of the classes which are to be extended which will search for missing methods in the languageProxy for the language code specified as the value. This allows linguistics methods to be called directly on extended objects directly (e.g., 12.en.ordinal becomes 12.ordinal). Obviously, methods which would collide with the object’s builtin methods will need to be invoked through the languageProxy. Any existing proxy methods in the extended classes will be preserved.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/linguistics.rb', line 263

def use( *languages )
	config = {}
	config = languages.pop if languages.last.is_a?( Hash )

	classes = config.key?( :classes ) ? config[:classes] : DefaultExtClasses
	classes = [ classes ] unless classes.is_a?( Array )

	# Install the languageProxy in each class.
	classes.each {|klass|

		# Create an languageProxy class for each installed language
		installLanguageProxy( klass, languages )

		# Install the delegator proxy if configured
		if config[:installProxy]
			case config[:installProxy]
			when Symbol
				langcode = config[:installProxy]
			when String
				langcode = config[:installProxy].intern
			when TrueClass
				langcode = DefaultLanguages[0]
			else
				raise ArgumentError,
					"Unexpected value %p for :installProxy" %
					config[:installProxy]
			end

			installDelegatorProxy( klass, langcode )
		end
	}
end