|
17 | 17 |
|
18 | 18 | "use strict" |
19 | 19 |
|
20 | | -# types.coffee (types.js v1.3.6) |
| 20 | +# types.coffee (types.js v1.4.2) |
21 | 21 |
|
22 | | -emptyNumber= -> |
23 | | - number= new Number |
24 | | - number.void= true |
25 | | - return number |
| 22 | +instanceOf = ( type, value ) -> value instanceof type |
| 23 | +# type defaults to object, for internal can do, saves for a few bytes.. |
| 24 | +typeOf = ( value, type= 'object' ) -> typeof value is type |
26 | 25 |
|
27 | | -Types= |
28 | | - parseIntBase: 10 |
29 | | - |
30 | | -literals= |
| 26 | +LITERALS= |
31 | 27 | 'Boolean' : false |
32 | 28 | 'String' : '' |
33 | | - 'Number' : emptyNumber() |
34 | 29 | 'Object' : {} |
35 | 30 | 'Array' : [] |
36 | 31 | 'Function' : -> |
| 32 | + 'Number' : do -> |
| 33 | + number= new Number |
| 34 | + number.void= true |
| 35 | + return number |
| 36 | + |
| 37 | +TYPES= |
| 38 | + 'Undefined' : ( value ) -> value is undefined |
| 39 | + 'Null' : ( value ) -> value is null |
| 40 | + 'Function' : ( value ) -> typeOf value, 'function' |
| 41 | + 'Boolean' : ( value ) -> typeOf value, 'boolean' |
| 42 | + 'String' : ( value ) -> typeOf value, 'string' |
| 43 | + 'Array' : ( value ) -> typeOf(value) and instanceOf Array, value |
| 44 | + 'RegExp' : ( value ) -> typeOf(value) and instanceOf RegExp, value |
| 45 | + 'Date' : ( value ) -> typeOf(value) and instanceOf Date, value |
| 46 | + 'Number' : ( value ) -> typeOf(value, 'number') and (value is value) or ( typeOf(value) and instanceOf(Number, value) ) |
| 47 | + 'Object' : ( value ) -> typeOf(value) and (value isnt null) and not instanceOf(Boolean, value) and not instanceOf(Number, value) and not instanceOf(Array, value) and not instanceOf(RegExp, value) and not instanceOf(Date, value) |
| 48 | + 'NaN' : ( value ) -> typeOf(value, 'number') and (value isnt value) |
| 49 | + 'Defined' : ( value ) -> value isnt undefined |
| 50 | + |
| 51 | +TYPES.StringOrNumber= (value) -> TYPES.String(value) or TYPES.Number(value) |
| 52 | + |
| 53 | +Types= _= |
| 54 | + # used by forceNumber to set the Radix, defaults to decimals |
| 55 | + parseIntBase: 10 |
37 | 56 |
|
38 | 57 | createForce= ( type ) -> |
39 | | - |
| 58 | + # convert value in case initial type test failed. failed conversion returns false |
40 | 59 | convertType= ( value ) -> |
41 | 60 | switch type |
42 | | - when 'Number' then return value if Types.isNumber value= parseInt value, Types.parseIntBase |
43 | | - when 'String' then return value+ '' if Types.isStringOrNumber value |
| 61 | + when 'Number' then return value if (_.isNumber value= parseInt value, _.parseIntBase) and not value.void |
| 62 | + when 'String' then return value+ '' if _.isStringOrNumber value |
44 | 63 | else return value if Types[ 'is'+ type ] value |
45 | | - return false |
46 | 64 |
|
| 65 | + # the forctType method, returns the type's defaultValue, if both value and replacement are not of, or convertible to, type |
47 | 66 | return ( value, replacement ) -> |
48 | | - return value if false isnt value= convertType value |
49 | | - return replacement if false isnt replacement= convertType replacement |
50 | | - return literals[ type ] |
| 67 | + return value if value? and undefined isnt value= convertType value |
| 68 | + return replacement if replacement? and undefined isnt replacement= convertType replacement |
| 69 | + return LITERALS[ type ] |
51 | 70 |
|
| 71 | +# test multiple values(arguments) for a given predicate. returns breakState if predicate is breakState for some value |
| 72 | +# when no break occured, ! breakState will be returned. |
52 | 73 | testValues= ( predicate, breakState, values= [] ) -> |
53 | | - if values.length < 1 |
54 | | - return true if predicate is typesPredicates.Undefined |
55 | | - return false |
| 74 | + # testing 'has' or 'all' for 'undefined' should return true on calls without arguments |
| 75 | + return ( predicate is TYPES.Undefined ) if values.length < 1 |
56 | 76 | for value in values |
57 | | - return breakState if (predicate value) is breakState |
| 77 | + return breakState if predicate(value) is breakState |
58 | 78 | return not breakState |
59 | 79 |
|
60 | | -typesPredicates= |
61 | | - 'Undefined' : (value) -> value is undefined |
62 | | - 'Null' : (value) -> value is null |
63 | | - 'Boolean' : (value) -> typeof value is 'boolean' |
64 | | - 'String' : (value) -> typeof value is 'string' |
65 | | - 'Function' : (value) -> typeof value is 'function' |
66 | | - 'Number' : (value) -> (typeof value is 'number') and (value is value) or ( (typeof value is 'object') and (value instanceof Number) and value.void ) |
67 | | - 'Array' : (value) -> (typeof value is 'object') and (value instanceof Array) |
68 | | - 'RegExp' : (value) -> (typeof value is 'object') and (value instanceof RegExp) |
69 | | - 'Date' : (value) -> (typeof value is 'object') and (value instanceof Date) |
70 | | - 'Object' : (value) -> (typeof value is 'object') and (value isnt null) and not (value instanceof Array) and not (value instanceof RegExp) and not (value instanceof Date) |
71 | | - 'NaN' : (value) -> (typeof value is 'number') and (value isnt value) |
72 | | - 'Defined' : (value) -> value isnt undefined |
73 | | - |
74 | | -typesPredicates.StringOrNumber= (value) -> typesPredicates['String'](value) or typesPredicates['Number'](value) |
75 | | - |
| 80 | +# generate all the is/not/has/all/force'Types' |
76 | 81 | breakIfEqual= true |
77 | | -do -> for name, predicate of typesPredicates then do ( name, predicate ) -> |
| 82 | +do -> for name, predicate of TYPES then do ( name, predicate ) -> |
78 | 83 | Types[ 'is'+ name ] = predicate |
79 | 84 | Types[ 'not'+ name ] = ( value ) -> not predicate value |
80 | 85 | Types[ 'has'+ name ] = -> testValues predicate, breakIfEqual, arguments |
81 | 86 | Types[ 'all'+ name ] = -> testValues predicate, not breakIfEqual, arguments |
82 | | - Types[ 'force'+ name ]= createForce name if name of literals |
| 87 | + # create only forceType of types found in LITERALS |
| 88 | + Types[ 'force'+ name ]= createForce name if name of LITERALS |
83 | 89 |
|
84 | 90 | Types.typeof= ( value ) -> |
85 | | - for type, predicate of typesPredicates |
86 | | - return type.toLowerCase() if predicate(value) is true |
87 | | - return 'unknown' |
| 91 | + for name, predicate of TYPES |
| 92 | + return name.toLowerCase() if predicate(value) is true |
88 | 93 |
|
89 | 94 | # end of types.coffee |
90 | 95 |
|
@@ -437,6 +442,17 @@ class Strings extends Chars |
437 | 442 | ending= new RegExp Strings.regEscape( ending )+ '$' |
438 | 443 | return ending.test string |
439 | 444 |
|
| 445 | + # @formatNumber: ( number, interval= 3 ) -> |
| 446 | + # return number if '' is number= _.forceString number |
| 447 | + # formatted= '' |
| 448 | + # length= number.length- 1 |
| 449 | + # interval= _.forceNumber interval, 3 |
| 450 | + # for index in [0..length] |
| 451 | + # formatted+= number[ index ] |
| 452 | + # if ( (length- index)% interval is 0 ) and ( index < length ) |
| 453 | + # formatted+= '.' |
| 454 | + # return formatted |
| 455 | + |
440 | 456 | # test below this line: |
441 | 457 | @wrap: ( prepend= '', append= '' ) -> |
442 | 458 | wrapper= ( string ) -> Strings.create prepend, string, append |
@@ -536,6 +552,8 @@ class Strings extends Chars |
536 | 552 |
|
537 | 553 | endsWith: ( ending ) -> Strings.endsWith @string, ending |
538 | 554 |
|
| 555 | + # formatNumber: ( formatting ) -> Strings.format @string, formatting |
| 556 | + |
539 | 557 | setWrap: ( prepend, append ) -> |
540 | 558 | if _.isNull @wrapMethod then @wrapMethod= Strings.wrap prepend, append |
541 | 559 | else @wrapMethod.wrap prepend, append |
|
0 commit comments