Linguistics

linguistics/iso639.rb - A hash of International 2- and 3-letter ISO639-1 and ISO639-2 language codes. Each entry has two keys:

:codes

All of the codes known for this language

:desc

The English-language description of the language.

Copyright (c) 2003-2008, Michael Granger All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the author/s, nor the names of the project's
  contributors may be used to endorse or promote products derived from this
  software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


A language-independent framework for adding linguistics functions to Ruby classes.

Synopsis

require 'linguistics'
Linguistics::use( :en )
MyClass::extend( Linguistics )

Authors

Copyright (c) 2003-2008, Michael Granger All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the author/s, nor the names of the project's
  contributors may be used to endorse or promote products derived from this
  software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Constants

DefaultExtClasses

The list of Classes to add linguistic behaviours to.

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.

LanguageCodes

Hash of ISO639 2- and 3-letter language codes

VERSION

Release version

Public Class Methods

const_missing( sym ) click to toggle source

Handle auto-magic usage

# File lib/linguistics.rb, line 233
def self::const_missing( sym )
    load_language( sym.to_s.downcase )
end
extend_object( obj ) click to toggle source

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.

# File lib/linguistics.rb, line 106
def self::extend_object( obj )
    case obj
    when Class
        # $stderr.puts "Extending %p" % obj if $DEBUG
        self::install_language_proxy( obj )
    else
        sclass = (class << obj; self; end)
        # $stderr.puts "Extending a object's metaclass: %p" % obj if $DEBUG
        self::install_language_proxy( sclass )
    end

    super
end
included( mod ) click to toggle source

Extend the including class with linguistics proxy methods.

# File lib/linguistics.rb, line 122
def self::included( mod )
    # $stderr.puts "Including Linguistics in %p" % mod if $DEBUG
    mod.extend( self ) unless mod == Linguistics
end
install_delegator_proxy( klass, langcode ) click to toggle source

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

# File lib/linguistics.rb, line 184
def self::install_delegator_proxy( klass, langcode )
    raise ArgumentError, "Missing langcode" if langcode.nil?

    # 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 %{
        def method_missing( sym, *args, &block )

            # If the linguistic delegator answers the message, install a
            # delegator method and call it.
            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, &block )
                        self.#{langcode}.\#{sym}( *args, &block )
                    end
                }
                self.method( sym ).call( *args, &block )

            # 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, &block )
                else
                    super( sym, *args, &block )
                end
            end
        end
    }
end
install_language_proxy( klass, languages=DefaultLanguages ) click to toggle source

Install the language proxy

# File lib/linguistics.rb, line 139
def self::install_language_proxy( klass, languages=DefaultLanguages )
    languages.replace( DefaultLanguages ) if languages.empty?

    # Create an languageProxy class for each language specified
    languages.each do |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 a languageProxy class that delegates to it, and
        # figure out what the languageProxy method will be called.
        mod = load_language( lang.to_s.downcase )
        ifaceMeth = mod.name.downcase.sub( /.*:/, '' )
        languageProxyClass = make_language_proxy( 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
end
make_language_proxy( mod ) click to toggle source

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

# File lib/linguistics.rb, line 130
def self::make_language_proxy( mod )
    # $stderr.puts "Making language proxy for mod %p" % [mod]
    Class::new( LanguageProxyClass ) {
        @langmod = mod
    }
end

Public Instance Methods

NUM() click to toggle source
Alias for: num
NUM=( val ) click to toggle source
Alias for: num=
classical=( val ) click to toggle source

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

# File lib/linguistics.rb, line 316
def classical=( val )
    Thread.current[:classical_plurals] = val
end
classical?() click to toggle source

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

# File lib/linguistics.rb, line 322
def classical?
    Thread.current[:classical_plurals] ? true : false
end
num() click to toggle source

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

# File lib/linguistics.rb, line 308
def num
    Thread.current[:persistent_count]
end
Also aliased as: NUM
num=( val ) click to toggle source

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

# File lib/linguistics.rb, line 301
def num=( val )
    Thread.current[:persistent_count] = val
end
Also aliased as: NUM=
use( *languages ) click to toggle source

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.

# File lib/linguistics.rb, line 261
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
        install_language_proxy( 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 = languages[0] || DefaultLanguages[0] || :en
            else
                raise ArgumentError,
                    "Unexpected value %p for :installProxy" %
                    config[:installProxy]
            end

            install_delegator_proxy( klass, langcode )
        end
    }
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.