lafcadio 0.4.3 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/lafcadio_schema +28 -0
- data/lib/lafcadio.rb +3 -4
- data/lib/lafcadio.rb~ +3 -4
- data/lib/lafcadio/TestSuite.rb +2 -0
- data/lib/lafcadio/TestSuite.rb~ +16 -0
- data/lib/lafcadio/dateTime.rb +93 -2
- data/lib/lafcadio/{dateTime/Month.rb → dateTime.rb~} +33 -33
- data/lib/lafcadio/depend.rb +3 -0
- data/lib/lafcadio/domain.rb +574 -70
- data/lib/lafcadio/domain.rb~ +570 -70
- data/lib/lafcadio/mock.rb +92 -2
- data/lib/lafcadio/mock.rb~ +93 -0
- data/lib/lafcadio/objectField.rb +614 -3
- data/lib/lafcadio/objectField.rb~ +618 -0
- data/lib/lafcadio/objectStore.rb +662 -19
- data/lib/lafcadio/objectStore.rb~ +746 -0
- data/lib/lafcadio/query.rb +415 -31
- data/lib/lafcadio/query.rb~ +572 -0
- data/lib/lafcadio/schema.rb +57 -2
- data/lib/lafcadio/test.rb +17 -2
- data/lib/lafcadio/{test/LafcadioTestCase.rb → test.rb~} +5 -5
- data/lib/lafcadio/test/testconfig.dat +1 -1
- data/lib/lafcadio/util.rb +337 -20
- metadata +16 -77
- data/lib/lafcadio/domain/DomainObject.rb +0 -375
- data/lib/lafcadio/domain/DomainObject.rb~ +0 -371
- data/lib/lafcadio/domain/MapObject.rb +0 -22
- data/lib/lafcadio/domain/ObjectType.rb +0 -80
- data/lib/lafcadio/includer.rb +0 -18
- data/lib/lafcadio/mock/MockDbBridge.rb +0 -78
- data/lib/lafcadio/mock/MockDbBridge.rb~ +0 -74
- data/lib/lafcadio/mock/MockObjectStore.rb +0 -20
- data/lib/lafcadio/objectField/AutoIncrementField.rb +0 -25
- data/lib/lafcadio/objectField/BooleanField.rb +0 -83
- data/lib/lafcadio/objectField/DateField.rb +0 -33
- data/lib/lafcadio/objectField/DateTimeField.rb +0 -25
- data/lib/lafcadio/objectField/DecimalField.rb +0 -41
- data/lib/lafcadio/objectField/EmailField.rb +0 -28
- data/lib/lafcadio/objectField/EnumField.rb +0 -62
- data/lib/lafcadio/objectField/FieldValueError.rb +0 -4
- data/lib/lafcadio/objectField/IntegerField.rb +0 -15
- data/lib/lafcadio/objectField/LinkField.rb +0 -92
- data/lib/lafcadio/objectField/LinkField.rb~ +0 -86
- data/lib/lafcadio/objectField/MoneyField.rb +0 -13
- data/lib/lafcadio/objectField/MonthField.rb +0 -16
- data/lib/lafcadio/objectField/ObjectField.rb +0 -142
- data/lib/lafcadio/objectField/PasswordField.rb +0 -29
- data/lib/lafcadio/objectField/StateField.rb +0 -13
- data/lib/lafcadio/objectField/SubsetLinkField.rb +0 -25
- data/lib/lafcadio/objectField/TextField.rb +0 -23
- data/lib/lafcadio/objectField/TextListField.rb +0 -21
- data/lib/lafcadio/objectField/TimeStampField.rb +0 -15
- data/lib/lafcadio/objectStore/Cache.rb +0 -81
- data/lib/lafcadio/objectStore/Committer.rb +0 -65
- data/lib/lafcadio/objectStore/CouldntMatchObjectTypeError.rb +0 -4
- data/lib/lafcadio/objectStore/DbBridge.rb +0 -140
- data/lib/lafcadio/objectStore/DbBridge.rb~ +0 -140
- data/lib/lafcadio/objectStore/DomainComparable.rb +0 -25
- data/lib/lafcadio/objectStore/DomainObjectInitError.rb +0 -9
- data/lib/lafcadio/objectStore/DomainObjectNotFoundError.rb +0 -4
- data/lib/lafcadio/objectStore/DomainObjectProxy.rb +0 -62
- data/lib/lafcadio/objectStore/DomainObjectSqlMaker.rb +0 -74
- data/lib/lafcadio/objectStore/ObjectStore.rb +0 -207
- data/lib/lafcadio/objectStore/ObjectStore.rb~ +0 -207
- data/lib/lafcadio/objectStore/SqlValueConverter.rb +0 -30
- data/lib/lafcadio/objectStore/SqlValueConverter.rb~ +0 -30
- data/lib/lafcadio/query/Compare.rb +0 -55
- data/lib/lafcadio/query/CompoundCondition.rb +0 -39
- data/lib/lafcadio/query/Condition.rb +0 -66
- data/lib/lafcadio/query/Condition.rb~ +0 -66
- data/lib/lafcadio/query/Equals.rb +0 -45
- data/lib/lafcadio/query/In.rb +0 -20
- data/lib/lafcadio/query/Like.rb +0 -48
- data/lib/lafcadio/query/Link.rb +0 -20
- data/lib/lafcadio/query/Max.rb +0 -32
- data/lib/lafcadio/query/Max.rb~ +0 -25
- data/lib/lafcadio/query/Not.rb +0 -21
- data/lib/lafcadio/query/Query.rb +0 -92
- data/lib/lafcadio/schema/CreateTableStatement.rb +0 -61
- data/lib/lafcadio/schema/CreateTableStatement.rb~ +0 -59
- data/lib/lafcadio/util/Context.rb +0 -61
- data/lib/lafcadio/util/ContextualService.rb +0 -33
- data/lib/lafcadio/util/English.rb +0 -117
- data/lib/lafcadio/util/HashOfArrays.rb +0 -48
- data/lib/lafcadio/util/LafcadioConfig.rb +0 -25
- data/lib/lafcadio/util/QueueHash.rb +0 -67
- data/lib/lafcadio/util/UsStates.rb +0 -29
- data/lib/lafcadio/xml.rb +0 -2
data/lib/lafcadio/query/Max.rb~
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module Lafcadio
|
2
|
-
class Query
|
3
|
-
class Max < Query #:nodoc:
|
4
|
-
attr_reader :field_name
|
5
|
-
|
6
|
-
def initialize( objectType, field_name = 'pkId' )
|
7
|
-
super( objectType )
|
8
|
-
@field_name = field_name
|
9
|
-
end
|
10
|
-
|
11
|
-
def collect( coll )
|
12
|
-
max = nil
|
13
|
-
coll.each { |d_obj|
|
14
|
-
a_value = d_obj.send( @field_name )
|
15
|
-
max = a_value if max.nil? || a_value > max
|
16
|
-
}
|
17
|
-
[ max ]
|
18
|
-
end
|
19
|
-
|
20
|
-
def fields
|
21
|
-
"max(#{ @field_name })"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/lafcadio/query/Not.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'lafcadio/query/Condition'
|
2
|
-
|
3
|
-
module Lafcadio
|
4
|
-
class Query
|
5
|
-
class Not < Condition #:nodoc:
|
6
|
-
def initialize(unCondition)
|
7
|
-
@unCondition = unCondition
|
8
|
-
end
|
9
|
-
|
10
|
-
def toSql
|
11
|
-
"!(#{ @unCondition.toSql })"
|
12
|
-
end
|
13
|
-
|
14
|
-
def objectMeets(obj)
|
15
|
-
!@unCondition.objectMeets(obj)
|
16
|
-
end
|
17
|
-
|
18
|
-
def objectType; @unCondition.objectType; end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/lafcadio/query/Query.rb
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
module Lafcadio
|
2
|
-
class Query #:nodoc:
|
3
|
-
ASC = 1
|
4
|
-
DESC = 2
|
5
|
-
|
6
|
-
attr_reader :objectType, :condition
|
7
|
-
attr_accessor :orderBy, :orderByOrder, :limit
|
8
|
-
|
9
|
-
def initialize(objectType, pkIdOrCondition = nil)
|
10
|
-
@objectType = objectType
|
11
|
-
( @condition, @orderBy, @limit ) = [ nil, nil, nil ]
|
12
|
-
if pkIdOrCondition
|
13
|
-
if pkIdOrCondition.class <= Condition
|
14
|
-
@condition = pkIdOrCondition
|
15
|
-
else
|
16
|
-
@condition = Query::Equals.new(objectType.sqlPrimaryKeyName,
|
17
|
-
pkIdOrCondition, objectType)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
@orderByOrder = ASC
|
21
|
-
end
|
22
|
-
|
23
|
-
def hash; toSql.hash; end
|
24
|
-
|
25
|
-
def eql?( other )
|
26
|
-
other.class <= Query && other.toSql == toSql
|
27
|
-
end
|
28
|
-
|
29
|
-
def tables
|
30
|
-
tableNames = []
|
31
|
-
anObjectType = objectType
|
32
|
-
until(DomainObject.abstractSubclasses.index(anObjectType) != nil ||
|
33
|
-
anObjectType == DomainObject)
|
34
|
-
tableNames.unshift anObjectType.tableName
|
35
|
-
anObjectType = anObjectType.superclass
|
36
|
-
end
|
37
|
-
tableNames.join ', '
|
38
|
-
end
|
39
|
-
|
40
|
-
def whereClause
|
41
|
-
whereClauses = []
|
42
|
-
anObjectType = objectType
|
43
|
-
superclass = anObjectType.superclass
|
44
|
-
until(DomainObject.abstractSubclasses.index(superclass) != nil ||
|
45
|
-
superclass == DomainObject)
|
46
|
-
joinClause = "#{ sqlPrimaryKeyField(superclass) } = " +
|
47
|
-
"#{ sqlPrimaryKeyField(anObjectType) }"
|
48
|
-
whereClauses.unshift joinClause
|
49
|
-
anObjectType = superclass
|
50
|
-
superclass = superclass.superclass
|
51
|
-
end
|
52
|
-
whereClauses << @condition.toSql if @condition
|
53
|
-
if whereClauses.size > 0
|
54
|
-
"where #{ whereClauses.join(' and ') }"
|
55
|
-
else
|
56
|
-
nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def sqlPrimaryKeyField(objectType)
|
61
|
-
"#{ objectType.tableName }.#{ objectType.sqlPrimaryKeyName }"
|
62
|
-
end
|
63
|
-
|
64
|
-
def fields
|
65
|
-
'*'
|
66
|
-
end
|
67
|
-
|
68
|
-
def orderClause
|
69
|
-
if @orderBy
|
70
|
-
clause = "order by #{ @orderBy } "
|
71
|
-
if @orderByOrder == ASC
|
72
|
-
clause += 'asc'
|
73
|
-
else
|
74
|
-
clause += 'desc'
|
75
|
-
end
|
76
|
-
clause
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def limitClause
|
81
|
-
"limit #{ @limit.begin }, #{ @limit.end - @limit.begin + 1 }" if @limit
|
82
|
-
end
|
83
|
-
|
84
|
-
def toSql
|
85
|
-
clauses = [ "select #{ fields }", "from #{ tables }" ]
|
86
|
-
clauses << whereClause if whereClause
|
87
|
-
clauses << orderClause if orderClause
|
88
|
-
clauses << limitClause if limitClause
|
89
|
-
clauses.join ' '
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
module Lafcadio
|
2
|
-
class CreateTableStatement #:nodoc:
|
3
|
-
def initialize( domainClass )
|
4
|
-
@domainClass = domainClass
|
5
|
-
end
|
6
|
-
|
7
|
-
def typeClause( field )
|
8
|
-
require 'lafcadio/objectField/TextField'
|
9
|
-
require 'lafcadio/objectField/DecimalField'
|
10
|
-
require 'lafcadio/objectField/LinkField'
|
11
|
-
require 'lafcadio/objectField/IntegerField'
|
12
|
-
require 'lafcadio/objectField/DateField'
|
13
|
-
require 'lafcadio/objectField/EnumField'
|
14
|
-
require 'lafcadio/objectField/TextListField'
|
15
|
-
require 'lafcadio/objectField/BooleanField'
|
16
|
-
require 'lafcadio/objectField/DateTimeField'
|
17
|
-
if ( field.class <= EnumField )
|
18
|
-
singleQuotedValues = field.enums.keys.collect! { |enumValue|
|
19
|
-
"'#{ enumValue }'"
|
20
|
-
}
|
21
|
-
"enum( #{ singleQuotedValues.join( ', ' ) } )"
|
22
|
-
elsif ( field.class <= TextField || field.class <= TextListField )
|
23
|
-
'varchar(255)'
|
24
|
-
elsif field.class <= DecimalField
|
25
|
-
"float(10, #{ field.precision })"
|
26
|
-
elsif ( field.class <= LinkField || field.class <= IntegerField )
|
27
|
-
'int'
|
28
|
-
elsif field.class <= DateField
|
29
|
-
'date'
|
30
|
-
elsif field.class <= BooleanField
|
31
|
-
'bool'
|
32
|
-
elsif field.class <= TimeStampField
|
33
|
-
'timestamp'
|
34
|
-
elsif field.class <= DateTimeField
|
35
|
-
'datetime'
|
36
|
-
elsif field.class <= BlobField
|
37
|
-
'blob'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def toSql
|
42
|
-
createDefinitions = []
|
43
|
-
createDefinitions << "#{ @domainClass.sqlPrimaryKeyName } " +
|
44
|
-
"int not null auto_increment"
|
45
|
-
createDefinitions << "primary key (#{ @domainClass.sqlPrimaryKeyName })"
|
46
|
-
@domainClass.classFields.each { |field|
|
47
|
-
definitionTerms = []
|
48
|
-
definitionTerms << field.dbFieldName
|
49
|
-
definitionTerms << typeClause( field )
|
50
|
-
definitionTerms << 'not null' if field.notNull
|
51
|
-
definitionTerms << 'unique' if field.unique
|
52
|
-
createDefinitions << definitionTerms.join(' ')
|
53
|
-
}
|
54
|
-
<<-SQL
|
55
|
-
create table #{ @domainClass.tableName } (
|
56
|
-
#{ createDefinitions.join(",\n ") }
|
57
|
-
);
|
58
|
-
SQL
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module Lafcadio
|
2
|
-
class CreateTableStatement #:nodoc:
|
3
|
-
def initialize( domainClass )
|
4
|
-
@domainClass = domainClass
|
5
|
-
end
|
6
|
-
|
7
|
-
def typeClause( field )
|
8
|
-
require 'lafcadio/objectField/TextField'
|
9
|
-
require 'lafcadio/objectField/DecimalField'
|
10
|
-
require 'lafcadio/objectField/LinkField'
|
11
|
-
require 'lafcadio/objectField/IntegerField'
|
12
|
-
require 'lafcadio/objectField/DateField'
|
13
|
-
require 'lafcadio/objectField/EnumField'
|
14
|
-
require 'lafcadio/objectField/TextListField'
|
15
|
-
require 'lafcadio/objectField/BooleanField'
|
16
|
-
require 'lafcadio/objectField/DateTimeField'
|
17
|
-
if ( field.class <= EnumField )
|
18
|
-
singleQuotedValues = field.enums.keys.collect! { |enumValue|
|
19
|
-
"'#{ enumValue }'"
|
20
|
-
}
|
21
|
-
"enum( #{ singleQuotedValues.join( ', ' ) } )"
|
22
|
-
elsif ( field.class <= TextField || field.class <= TextListField )
|
23
|
-
'varchar(255)'
|
24
|
-
elsif field.class <= DecimalField
|
25
|
-
"float(10, #{ field.precision })"
|
26
|
-
elsif ( field.class <= LinkField || field.class <= IntegerField )
|
27
|
-
'int'
|
28
|
-
elsif field.class <= DateField
|
29
|
-
'date'
|
30
|
-
elsif field.class <= BooleanField
|
31
|
-
'bool'
|
32
|
-
elsif field.class <= TimeStampField
|
33
|
-
'timestamp'
|
34
|
-
elsif field.class <= DateTimeField
|
35
|
-
'datetime'
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def toSql
|
40
|
-
createDefinitions = []
|
41
|
-
createDefinitions << "#{ @domainClass.sqlPrimaryKeyName } " +
|
42
|
-
"int not null auto_increment"
|
43
|
-
createDefinitions << "primary key (#{ @domainClass.sqlPrimaryKeyName })"
|
44
|
-
@domainClass.classFields.each { |field|
|
45
|
-
definitionTerms = []
|
46
|
-
definitionTerms << field.dbFieldName
|
47
|
-
definitionTerms << typeClause( field )
|
48
|
-
definitionTerms << 'not null' if field.notNull
|
49
|
-
definitionTerms << 'unique' if field.unique
|
50
|
-
createDefinitions << definitionTerms.join(' ')
|
51
|
-
}
|
52
|
-
<<-SQL
|
53
|
-
create table #{ @domainClass.tableName } (
|
54
|
-
#{ createDefinitions.join(",\n ") }
|
55
|
-
);
|
56
|
-
SQL
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
|
-
module Lafcadio
|
4
|
-
# The Context is a singleton object that manages ContextualServices. Each
|
5
|
-
# ContextualService is a service that connects in some way to external
|
6
|
-
# resources: ObjectStore connects to the database; Emailer connects to SMTP,
|
7
|
-
# etc.
|
8
|
-
#
|
9
|
-
# Context makes it easy to ensure that each ContextualService is only
|
10
|
-
# instantiated once, which can be quite useful for services with expensive
|
11
|
-
# creation.
|
12
|
-
#
|
13
|
-
# Furthermore, Context allows you to explicitly set instances for a given
|
14
|
-
# service, which can be quite useful in testing. For example, once
|
15
|
-
# LafcadioTestCase#setup has an instance of MockObjectStore, it calls
|
16
|
-
# context.setObjectStore @mockObjectStore
|
17
|
-
# which ensures that any future calls to ObjectStore.getObjectStore will
|
18
|
-
# return @mockObjectStore, instead of an instance of ObjectStore connecting
|
19
|
-
# test code to a live database.
|
20
|
-
class Context
|
21
|
-
include Singleton
|
22
|
-
|
23
|
-
def initialize
|
24
|
-
@resources = {}
|
25
|
-
end
|
26
|
-
|
27
|
-
# Flushes all cached ContextualServices.
|
28
|
-
def flush
|
29
|
-
@resources = {}
|
30
|
-
end
|
31
|
-
|
32
|
-
def createInstance(resourceName) #:nodoc:
|
33
|
-
resourceClass = eval resourceName
|
34
|
-
resourceClass.new self
|
35
|
-
end
|
36
|
-
|
37
|
-
def getResource(resourceName) #:nodoc:
|
38
|
-
resource = @resources[resourceName]
|
39
|
-
unless resource
|
40
|
-
resource = createInstance resourceName
|
41
|
-
setResource resourceName, resource
|
42
|
-
end
|
43
|
-
resource
|
44
|
-
end
|
45
|
-
|
46
|
-
def setResource(resourceName, resource) #:nodoc:
|
47
|
-
@resources[resourceName] = resource
|
48
|
-
end
|
49
|
-
|
50
|
-
def method_missing(methId, *args) #:nodoc:
|
51
|
-
methodName = methId.id2name
|
52
|
-
if methodName =~ /^get(.*)$/
|
53
|
-
getResource $1
|
54
|
-
elsif methodName =~ /^set(.*)$/
|
55
|
-
setResource $1, args[0]
|
56
|
-
else
|
57
|
-
super
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'lafcadio/util/Context'
|
2
|
-
|
3
|
-
module Lafcadio
|
4
|
-
# A ContextualService is a service that is managed by the Context.
|
5
|
-
# ContextualServices are not instantiated normally. Instead, the instance of
|
6
|
-
# such a service may be retrieved by calling the method
|
7
|
-
# < class name >.get< class name >
|
8
|
-
#
|
9
|
-
# For example: ObjectStore.getObjectStore
|
10
|
-
class ContextualService
|
11
|
-
def ContextualService.method_missing(methodId)
|
12
|
-
methodName = methodId.id2name
|
13
|
-
if methodName =~ /^get.*/
|
14
|
-
Context.instance.send(methodName)
|
15
|
-
else
|
16
|
-
super methodId
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# The +passKey+ needs to be the Context instance, or else this method fails.
|
21
|
-
# Note that this isn't hard security of any kind; it's simply a gentle
|
22
|
-
# reminder to users of a ContextualService that the class should not be
|
23
|
-
# instantiated directly.
|
24
|
-
def initialize(passKey)
|
25
|
-
if passKey.class != Context
|
26
|
-
raise ArgumentError,
|
27
|
-
"#{ self.class.name.to_s } should only be instantiated by a " +
|
28
|
-
"Context",
|
29
|
-
caller
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
module Lafcadio
|
2
|
-
# A collection of English-language specific utility methods.
|
3
|
-
class English
|
4
|
-
# Turns a camel-case string ("camelCaseToEnglish") to plain English ("camel
|
5
|
-
# case to english"). Each word is decapitalized.
|
6
|
-
def English.camelCaseToEnglish(camelCaseStr)
|
7
|
-
words = []
|
8
|
-
nextCapIndex =(camelCaseStr =~ /[A-Z]/)
|
9
|
-
while nextCapIndex != nil
|
10
|
-
words << $` if $`.size > 0
|
11
|
-
camelCaseStr = $& + $'
|
12
|
-
camelCaseStr[0] = camelCaseStr[0..0].downcase
|
13
|
-
nextCapIndex =(camelCaseStr =~ /[A-Z]/)
|
14
|
-
end
|
15
|
-
words << camelCaseStr
|
16
|
-
words.join ' '
|
17
|
-
end
|
18
|
-
|
19
|
-
# Given a format for a template sentence, generates the sentence while
|
20
|
-
# accounting for details such as pluralization and whether to use "a" or
|
21
|
-
# "an".
|
22
|
-
# [format] The format string. Format codes are:
|
23
|
-
# * %num: Number
|
24
|
-
# * %is: Transitive verb. This will be turned into "is" or "are",
|
25
|
-
# depending on <tt>number</tt>.
|
26
|
-
# * %nam: Name. This will be rendered as either singular or
|
27
|
-
# plural, depending on <tt>number</tt>.
|
28
|
-
# * %a: Indefinite article. This will be turned into "a" or "an",
|
29
|
-
# depending on <tt>name</tt>.
|
30
|
-
# [name] The name of the object being described.
|
31
|
-
# [number] The number of the objects being describes.
|
32
|
-
#
|
33
|
-
# Examples:
|
34
|
-
# English.sentence("There %is currently %num %nam", "product category",
|
35
|
-
# 0) -> "There are currently 0 product categories"
|
36
|
-
# English.sentence("There %is currently %num %nam", "product category",
|
37
|
-
# 1) -> "There is currently 1 product category"
|
38
|
-
# English.sentence("Add %a %nam", "invoice") -> "Add an invoice"
|
39
|
-
def English.sentence(format, name, number = 1)
|
40
|
-
sentence = format
|
41
|
-
sentence.gsub!( /%num/, number.to_s )
|
42
|
-
isVerb = number == 1 ? "is" : "are"
|
43
|
-
sentence.gsub!( /%is/, isVerb )
|
44
|
-
name = English.plural name if number != 1
|
45
|
-
sentence.gsub!( /%nam/, name )
|
46
|
-
article = startsWithVowelSound(name) ? 'an' : 'a'
|
47
|
-
sentence.gsub!( /%a/, article )
|
48
|
-
sentence
|
49
|
-
end
|
50
|
-
|
51
|
-
# Does this word start with a vowel sound? "User" and "usury" don't, but
|
52
|
-
# "ugly" does.
|
53
|
-
def English.startsWithVowelSound(word)
|
54
|
-
uSomethingUMatch = word =~ /^u[^aeiuo][aeiou]/
|
55
|
-
# 'user' and 'usury' don't start with a vowel sound
|
56
|
-
word =~ /^[aeiou]/ && !uSomethingUMatch
|
57
|
-
end
|
58
|
-
|
59
|
-
# Given a singular noun, returns the plural form.
|
60
|
-
def English.plural(singular)
|
61
|
-
consonantYPattern = Regexp.new("([^aeiou])y$", Regexp::IGNORECASE)
|
62
|
-
if singular =~ consonantYPattern
|
63
|
-
singular.gsub consonantYPattern, '\1ies'
|
64
|
-
elsif singular =~ /[xs]$/
|
65
|
-
singular + "es"
|
66
|
-
else
|
67
|
-
singular + "s"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Returns the proper noun form of a string by capitalizing most of the
|
72
|
-
# words.
|
73
|
-
#
|
74
|
-
# Examples:
|
75
|
-
# English.properNoun("bosnia and herzegovina") ->
|
76
|
-
# "Bosnia and Herzegovina"
|
77
|
-
# English.properNoun("macedonia, the former yugoslav republic of") ->
|
78
|
-
# "Macedonia, the Former Yugoslav Republic of"
|
79
|
-
# English.properNoun("virgin islands, u.s.") ->
|
80
|
-
# "Virgin Islands, U.S."
|
81
|
-
def English.properNoun(string)
|
82
|
-
properNoun = ""
|
83
|
-
while(matchIndex = string =~ /[\. ]/)
|
84
|
-
word = string[0..matchIndex-1]
|
85
|
-
word = word.capitalize unless [ 'and', 'the', 'of' ].index(word) != nil
|
86
|
-
properNoun += word + $&
|
87
|
-
string = string[matchIndex+1..string.length]
|
88
|
-
end
|
89
|
-
word = string
|
90
|
-
word = word.capitalize unless [ 'and', 'the', 'of' ].index(word) != nil
|
91
|
-
properNoun += word
|
92
|
-
properNoun
|
93
|
-
end
|
94
|
-
|
95
|
-
# Given a noun in plural form, returns its singular version.
|
96
|
-
def English.singular(plural)
|
97
|
-
if plural =~ /(.*)ies/
|
98
|
-
$1 + 'y'
|
99
|
-
elsif plural =~ /(.*s)es/
|
100
|
-
$1
|
101
|
-
else
|
102
|
-
plural =~ /(.*)s/
|
103
|
-
$1
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
# Turns an English language string into camel case.
|
108
|
-
def English.englishToCamelCase(englishStr)
|
109
|
-
cc = ""
|
110
|
-
englishStr.split.each { |word|
|
111
|
-
word = word.capitalize unless cc == ''
|
112
|
-
cc = cc += word
|
113
|
-
}
|
114
|
-
cc
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|