fancy 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +7 -0
- data/LICENSE +19 -0
- data/README +173 -0
- data/Rakefile +255 -0
- data/bin/fancy +40 -0
- data/bin/fdoc +23 -0
- data/bin/fyi +22 -0
- data/bin/ifancy +46 -0
- data/boot/README +12 -0
- data/boot/code_loader.rb +165 -0
- data/boot/compile.fy +3 -0
- data/boot/fancy_ext.rb +13 -0
- data/boot/fancy_ext/block_env.rb +29 -0
- data/boot/fancy_ext/class.rb +26 -0
- data/boot/fancy_ext/kernel.rb +12 -0
- data/boot/fancy_ext/module.rb +89 -0
- data/boot/fancy_ext/object.rb +34 -0
- data/boot/fancy_ext/string_helper.rb +10 -0
- data/boot/load.rb +72 -0
- data/boot/rbx-compiler/README +12 -0
- data/boot/rbx-compiler/compiler.rb +24 -0
- data/boot/rbx-compiler/compiler/ast.rb +23 -0
- data/boot/rbx-compiler/compiler/ast/README +11 -0
- data/boot/rbx-compiler/compiler/ast/array_literal.rb +13 -0
- data/boot/rbx-compiler/compiler/ast/assign.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/block.rb +70 -0
- data/boot/rbx-compiler/compiler/ast/class_def.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/expression_list.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/hash_literal.rb +11 -0
- data/boot/rbx-compiler/compiler/ast/identifier.rb +120 -0
- data/boot/rbx-compiler/compiler/ast/match.rb +81 -0
- data/boot/rbx-compiler/compiler/ast/message_send.rb +71 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +116 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +6 -0
- data/boot/rbx-compiler/compiler/ast/range_literal.rb +22 -0
- data/boot/rbx-compiler/compiler/ast/require.rb +20 -0
- data/boot/rbx-compiler/compiler/ast/return.rb +29 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/script.rb +56 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +39 -0
- data/boot/rbx-compiler/compiler/ast/string_literal.rb +14 -0
- data/boot/rbx-compiler/compiler/ast/super.rb +25 -0
- data/boot/rbx-compiler/compiler/ast/try_catch_block.rb +220 -0
- data/boot/rbx-compiler/compiler/ast/tuple_literal.rb +33 -0
- data/boot/rbx-compiler/compiler/command.rb +39 -0
- data/boot/rbx-compiler/compiler/compiler.rb +83 -0
- data/boot/rbx-compiler/compiler/stages.rb +99 -0
- data/boot/rbx-compiler/parser.rb +2 -0
- data/boot/rbx-compiler/parser/README +15 -0
- data/boot/rbx-compiler/parser/Rakefile +54 -0
- data/boot/rbx-compiler/parser/extconf.rb +3 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/fancy_parser.c +46 -0
- data/boot/rbx-compiler/parser/fancy_parser.h +8 -0
- data/boot/rbx-compiler/parser/lexer.lex +180 -0
- data/boot/rbx-compiler/parser/parser.rb +356 -0
- data/boot/rbx-compiler/parser/parser.y +711 -0
- data/boot/rsexp_pretty_printer.rb +76 -0
- data/doc/api/fancy.css +93 -0
- data/doc/api/fancy.jsonp +1 -0
- data/doc/api/fdoc.js +187 -0
- data/doc/api/index.html +57 -0
- data/doc/api/underscore-min.js +18 -0
- data/doc/features.md +228 -0
- data/examples/argv.fy +8 -0
- data/examples/arithmetic.fy +7 -0
- data/examples/armstrong_numbers.fy +33 -0
- data/examples/array.fy +52 -0
- data/examples/blocks.fy +15 -0
- data/examples/boolean.fy +24 -0
- data/examples/call_with_receiver.fy +9 -0
- data/examples/class.fy +68 -0
- data/examples/closures.fy +24 -0
- data/examples/constant_access.fy +15 -0
- data/examples/default_args.fy +17 -0
- data/examples/define_methods.fy +15 -0
- data/examples/documentation.fy +57 -0
- data/examples/documentation_formatters.fy +25 -0
- data/examples/echo.fy +16 -0
- data/examples/empty_catch.fy +4 -0
- data/examples/exception.fy +9 -0
- data/examples/factorial.fy +12 -0
- data/examples/fibonacci.fy +16 -0
- data/examples/files.fy +23 -0
- data/examples/finally.fy +5 -0
- data/examples/game_of_life.fy +148 -0
- data/examples/hashes.fy +7 -0
- data/examples/hello_world.fy +6 -0
- data/examples/html_generator.fy +54 -0
- data/examples/implicit_return.fy +3 -0
- data/examples/matchers.fy +6 -0
- data/examples/methods.fy +29 -0
- data/examples/nested_classes.fy +27 -0
- data/examples/nested_try.fy +9 -0
- data/examples/numbers.fy +12 -0
- data/examples/pattern_matching.fy +40 -0
- data/examples/person.fy +65 -0
- data/examples/project-euler/01.fy +8 -0
- data/examples/project-euler/02.fy +21 -0
- data/examples/project-euler/28.fy +33 -0
- data/examples/rbx/and_or.fy +7 -0
- data/examples/rbx/blocks.fy +22 -0
- data/examples/rbx/classes.fy +32 -0
- data/examples/rbx/hello.fy +8 -0
- data/examples/rbx/include.fy +12 -0
- data/examples/rbx/inherit.fy +11 -0
- data/examples/rbx/methods.fy +15 -0
- data/examples/rbx/nested_classes.fy +9 -0
- data/examples/rbx/require.fy +3 -0
- data/examples/rbx/strings.fy +5 -0
- data/examples/regex.fy +7 -0
- data/examples/require.fy +7 -0
- data/examples/retry.fy +12 -0
- data/examples/return.fy +13 -0
- data/examples/ruby_require.fy +7 -0
- data/examples/ruby_send.fy +3 -0
- data/examples/singleton_methods.fy +21 -0
- data/examples/stupid_quicksort.fy +12 -0
- data/examples/threads.fy +18 -0
- data/examples/tuple.fy +8 -0
- data/examples/webserver/webserver.fy +18 -0
- data/lib/argv.fy +36 -0
- data/lib/array.fy +207 -0
- data/lib/block.fy +88 -0
- data/lib/boot.fy +41 -0
- data/lib/class.fy +106 -0
- data/lib/compiler.fy +14 -0
- data/lib/compiler/ast.fy +40 -0
- data/lib/compiler/ast/assign.fy +96 -0
- data/lib/compiler/ast/block.fy +84 -0
- data/lib/compiler/ast/class_def.fy +33 -0
- data/lib/compiler/ast/expression_list.fy +47 -0
- data/lib/compiler/ast/identifier.fy +113 -0
- data/lib/compiler/ast/literals.fy +122 -0
- data/lib/compiler/ast/match.fy +88 -0
- data/lib/compiler/ast/message_send.fy +110 -0
- data/lib/compiler/ast/method_def.fy +90 -0
- data/lib/compiler/ast/node.fy +7 -0
- data/lib/compiler/ast/range.fy +16 -0
- data/lib/compiler/ast/require.fy +15 -0
- data/lib/compiler/ast/return.fy +23 -0
- data/lib/compiler/ast/script.fy +52 -0
- data/lib/compiler/ast/singleton_method_def.fy +35 -0
- data/lib/compiler/ast/super.fy +17 -0
- data/lib/compiler/ast/try_catch.fy +176 -0
- data/lib/compiler/ast/tuple_literal.fy +34 -0
- data/lib/compiler/command.fy +51 -0
- data/lib/compiler/compiler.fy +73 -0
- data/lib/compiler/stages.fy +81 -0
- data/lib/directory.fy +17 -0
- data/lib/documentation.fy +115 -0
- data/lib/enumerable.fy +269 -0
- data/lib/eval.fy +31 -0
- data/lib/fancy_spec.fy +202 -0
- data/lib/fdoc.fy +359 -0
- data/lib/fdoc_hook.fy +10 -0
- data/lib/file.fy +54 -0
- data/lib/hash.fy +56 -0
- data/lib/main.fy +80 -0
- data/lib/method.fy +22 -0
- data/lib/nil_class.fy +56 -0
- data/lib/number.fy +87 -0
- data/lib/object.fy +170 -0
- data/lib/package.fy +61 -0
- data/lib/package/dependency.fy +24 -0
- data/lib/package/installer.fy +180 -0
- data/lib/package/specification.fy +55 -0
- data/lib/package/uninstaller.fy +15 -0
- data/lib/parser.fy +4 -0
- data/lib/parser/ext/README +15 -0
- data/lib/parser/ext/ext.c +42 -0
- data/lib/parser/ext/ext.h +8 -0
- data/lib/parser/ext/extconf.rb +3 -0
- data/lib/parser/ext/lexer.lex +187 -0
- data/lib/parser/ext/parser.y +744 -0
- data/lib/parser/methods.fy +297 -0
- data/lib/rbx.fy +37 -0
- data/lib/rbx/array.fy +237 -0
- data/lib/rbx/bignum.fy +23 -0
- data/lib/rbx/block.fy +9 -0
- data/lib/rbx/class.fy +129 -0
- data/lib/rbx/code_loader.fy +192 -0
- data/lib/rbx/console.fy +63 -0
- data/lib/rbx/directory.fy +46 -0
- data/lib/rbx/documentation.fy +64 -0
- data/lib/rbx/environment_variables.fy +3 -0
- data/lib/rbx/exception.fy +30 -0
- data/lib/rbx/false_class.fy +58 -0
- data/lib/rbx/fiber.fy +25 -0
- data/lib/rbx/file.fy +191 -0
- data/lib/rbx/fixnum.fy +25 -0
- data/lib/rbx/float.fy +14 -0
- data/lib/rbx/hash.fy +38 -0
- data/lib/rbx/integer.fy +15 -0
- data/lib/rbx/io.fy +30 -0
- data/lib/rbx/match_data.fy +9 -0
- data/lib/rbx/method.fy +22 -0
- data/lib/rbx/name_error.fy +3 -0
- data/lib/rbx/no_method_error.fy +15 -0
- data/lib/rbx/object.fy +117 -0
- data/lib/rbx/range.fy +15 -0
- data/lib/rbx/regexp.fy +9 -0
- data/lib/rbx/string.fy +63 -0
- data/lib/rbx/symbol.fy +12 -0
- data/lib/rbx/system.fy +37 -0
- data/lib/rbx/tcp_server.fy +6 -0
- data/lib/rbx/tcp_socket.fy +7 -0
- data/lib/rbx/thread.fy +75 -0
- data/lib/rbx/tuple.fy +37 -0
- data/lib/set.fy +61 -0
- data/lib/stack.fy +51 -0
- data/lib/string.fy +58 -0
- data/lib/struct.fy +13 -0
- data/lib/symbol.fy +23 -0
- data/lib/true_class.fy +43 -0
- data/lib/tuple.fy +68 -0
- data/lib/version.fy +6 -0
- data/tests/argv.fy +13 -0
- data/tests/array.fy +343 -0
- data/tests/assignment.fy +53 -0
- data/tests/block.fy +103 -0
- data/tests/class.fy +409 -0
- data/tests/control_flow.fy +79 -0
- data/tests/documentation.fy +24 -0
- data/tests/exception.fy +115 -0
- data/tests/file.fy +86 -0
- data/tests/hash.fy +101 -0
- data/tests/method.fy +131 -0
- data/tests/nil_class.fy +55 -0
- data/tests/number.fy +128 -0
- data/tests/object.fy +125 -0
- data/tests/parsing/sexp.fy +50 -0
- data/tests/pattern_matching.fy +82 -0
- data/tests/range.fy +11 -0
- data/tests/set.fy +10 -0
- data/tests/stack.fy +22 -0
- data/tests/string.fy +102 -0
- data/tests/symbol.fy +17 -0
- data/tests/true_class.fy +63 -0
- data/tests/tuple.fy +21 -0
- data/tools/fancy-mode.el +63 -0
- metadata +321 -0
data/lib/rbx/tuple.fy
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
Tuple = Rubinius Tuple
|
2
|
+
class Tuple {
|
3
|
+
ruby_alias: 'size
|
4
|
+
|
5
|
+
def initialize: size {
|
6
|
+
"""
|
7
|
+
@size Size of the @Tuple@ (amount of values to hold).
|
8
|
+
|
9
|
+
Initializes a new @Tuple@ with a given amount of element slots.
|
10
|
+
E.g. if @size is @2, creates a 2-Tuple.
|
11
|
+
"""
|
12
|
+
|
13
|
+
initialize(size)
|
14
|
+
}
|
15
|
+
|
16
|
+
def at: idx {
|
17
|
+
"""
|
18
|
+
@idx Index for the element to get.
|
19
|
+
@return Element at the given index within the @Tuple@ or @nil.
|
20
|
+
|
21
|
+
Returns an element at a given indes.
|
22
|
+
Possibly throws an @Rubinius::ObjectBoundsExceededError@.
|
23
|
+
"""
|
24
|
+
|
25
|
+
at(idx)
|
26
|
+
}
|
27
|
+
|
28
|
+
def at: idx put: val {
|
29
|
+
"""
|
30
|
+
@idx Index of element to set.
|
31
|
+
@val Value to set at given index.
|
32
|
+
|
33
|
+
Sets a value for a given index within a @Tuple@.
|
34
|
+
"""
|
35
|
+
put(idx, val)
|
36
|
+
}
|
37
|
+
}
|
data/lib/set.fy
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
class Set {
|
2
|
+
"A simple Set data structure class."
|
3
|
+
|
4
|
+
include: FancyEnumerable
|
5
|
+
read_slots: ['values]
|
6
|
+
|
7
|
+
def initialize: arr {
|
8
|
+
"Initialize a new Set with a given Array of values."
|
9
|
+
@values = arr uniq
|
10
|
+
}
|
11
|
+
|
12
|
+
def initialize {
|
13
|
+
"Initialize a new empty Set."
|
14
|
+
@values = []
|
15
|
+
}
|
16
|
+
|
17
|
+
def == other {
|
18
|
+
"Indicates, if two Sets are equal."
|
19
|
+
if: (other is_a?: Set) then: {
|
20
|
+
@values == (other values)
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
def Set [] arr {
|
25
|
+
"Initialize a new Array with a given Array of values."
|
26
|
+
Set new: arr
|
27
|
+
}
|
28
|
+
|
29
|
+
def << value {
|
30
|
+
"Insert a value into the Set."
|
31
|
+
{ @values << value } unless: (includes?: value)
|
32
|
+
}
|
33
|
+
|
34
|
+
def includes?: value {
|
35
|
+
"Indicates, if the Set includes a given value."
|
36
|
+
@values includes?: value
|
37
|
+
}
|
38
|
+
|
39
|
+
def each: block {
|
40
|
+
"Calls a given Block for each element of the Set."
|
41
|
+
@values each: block
|
42
|
+
}
|
43
|
+
|
44
|
+
def unknown_message: msg with_params: params {
|
45
|
+
if: (params empty?) then: {
|
46
|
+
@values send: msg
|
47
|
+
} else: {
|
48
|
+
@values send: msg params: params
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
def to_s {
|
53
|
+
"Returns a String representation of a Set."
|
54
|
+
"Set" ++ @values to_s
|
55
|
+
}
|
56
|
+
|
57
|
+
def inspect {
|
58
|
+
"Returns a detailed String representation of a Set."
|
59
|
+
self to_s ++ " : Set"
|
60
|
+
}
|
61
|
+
}
|
data/lib/stack.fy
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
class Stack {
|
2
|
+
"""
|
3
|
+
A simple Stack container class.
|
4
|
+
"""
|
5
|
+
|
6
|
+
def initialize {
|
7
|
+
@arr = []
|
8
|
+
}
|
9
|
+
|
10
|
+
def initialize: size {
|
11
|
+
"Initializes a new Stack with a given size."
|
12
|
+
|
13
|
+
@arr = Array new: size
|
14
|
+
}
|
15
|
+
|
16
|
+
def push: obj {
|
17
|
+
"Pushes a value onto the Stack."
|
18
|
+
|
19
|
+
@arr << obj
|
20
|
+
}
|
21
|
+
|
22
|
+
def << obj {
|
23
|
+
"Same as Stack#push:."
|
24
|
+
|
25
|
+
@arr << obj
|
26
|
+
}
|
27
|
+
|
28
|
+
def pop {
|
29
|
+
"Pops the top-of-stack element from the Stack and returns it."
|
30
|
+
|
31
|
+
@arr remove_at: (self size - 1)
|
32
|
+
}
|
33
|
+
|
34
|
+
def top {
|
35
|
+
"Returns the top-of-stack element."
|
36
|
+
|
37
|
+
@arr last
|
38
|
+
}
|
39
|
+
|
40
|
+
def size {
|
41
|
+
"Returns the size of the Stack."
|
42
|
+
|
43
|
+
@arr size
|
44
|
+
}
|
45
|
+
|
46
|
+
def empty? {
|
47
|
+
"Indicates, if the Stack is empty."
|
48
|
+
|
49
|
+
@arr empty?
|
50
|
+
}
|
51
|
+
}
|
data/lib/string.fy
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
class String {
|
2
|
+
"""
|
3
|
+
Strings are sequences of characters and behave as such.
|
4
|
+
All literal Strings within Fancy code are instances of the String
|
5
|
+
class.
|
6
|
+
|
7
|
+
They also include FancyEnumerable, which means you can use all the
|
8
|
+
common sequence methods on them, like +map:+, +select:+ etc.
|
9
|
+
"""
|
10
|
+
|
11
|
+
include: FancyEnumerable
|
12
|
+
|
13
|
+
def ++ other {
|
14
|
+
"Concatenate the String with another String"
|
15
|
+
|
16
|
+
self + (other to_s)
|
17
|
+
}
|
18
|
+
|
19
|
+
def whitespace? {
|
20
|
+
"Indicates, if a String is empty or a single whitespace character."
|
21
|
+
|
22
|
+
self empty? or: (self == " ")
|
23
|
+
}
|
24
|
+
|
25
|
+
def blank? {
|
26
|
+
"Indicates, if a String consists only of whitespace."
|
27
|
+
|
28
|
+
self =~ /^\s*$/ if_do: {
|
29
|
+
true
|
30
|
+
} else: {
|
31
|
+
false
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
def * num {
|
36
|
+
"Returns a string that is the num-fold concatenation of itself."
|
37
|
+
|
38
|
+
str = ""
|
39
|
+
num to_i times: {
|
40
|
+
str = str ++ self
|
41
|
+
}
|
42
|
+
str
|
43
|
+
}
|
44
|
+
|
45
|
+
def words {
|
46
|
+
self split
|
47
|
+
}
|
48
|
+
|
49
|
+
def raise! {
|
50
|
+
"Raises a new StdError with self as the message."
|
51
|
+
StdError new: self . raise!
|
52
|
+
}
|
53
|
+
|
54
|
+
def rest {
|
55
|
+
"Returns a @String@ containing all but the first character."
|
56
|
+
from: 1 to: -1
|
57
|
+
}
|
58
|
+
}
|
data/lib/struct.fy
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class Struct {
|
2
|
+
def Struct new: fields {
|
3
|
+
struct = ruby: "new" args: fields
|
4
|
+
struct read_write_slots: fields
|
5
|
+
struct define_method: "new:" with: |values| {
|
6
|
+
instance = struct new()
|
7
|
+
fields each_with_index: |f i| {
|
8
|
+
instance send: f params: [values at: i]
|
9
|
+
}
|
10
|
+
}
|
11
|
+
struct
|
12
|
+
}
|
13
|
+
}
|
data/lib/symbol.fy
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Symbol {
|
2
|
+
"""
|
3
|
+
Symbols are unique identifiers and only created once.
|
4
|
+
|
5
|
+
If there are several occurrances of the same Symbol literal within
|
6
|
+
Fancy code, they all refer to the same Symbol object.
|
7
|
+
"""
|
8
|
+
|
9
|
+
def call: arg {
|
10
|
+
"""
|
11
|
+
This allows Symbols to be used like Blocks
|
12
|
+
(e.g. in all methods of Enumerable).
|
13
|
+
Example: [1, 2, 3] map: 'squared # => [1, 4, 9]
|
14
|
+
"""
|
15
|
+
|
16
|
+
if: (arg is_a?: Array) then: {
|
17
|
+
arg first send: self params: $ arg rest
|
18
|
+
} else: {
|
19
|
+
arg send: self
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
}
|
data/lib/true_class.fy
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
class TrueClass {
|
2
|
+
"TrueClass. The class of the singleton true value."
|
3
|
+
|
4
|
+
def TrueClass new {
|
5
|
+
# always return true singleton object when trying to create a new
|
6
|
+
# TrueClass instance
|
7
|
+
true
|
8
|
+
}
|
9
|
+
|
10
|
+
def if_true: then_block else: else_block {
|
11
|
+
"Calls the then_block."
|
12
|
+
then_block call
|
13
|
+
}
|
14
|
+
|
15
|
+
def if_true: block {
|
16
|
+
"Calls the block."
|
17
|
+
block call
|
18
|
+
}
|
19
|
+
|
20
|
+
def if_false: block {
|
21
|
+
"Returns nil."
|
22
|
+
nil
|
23
|
+
}
|
24
|
+
|
25
|
+
def nil? {
|
26
|
+
"Returns nil."
|
27
|
+
false
|
28
|
+
}
|
29
|
+
|
30
|
+
def false? {
|
31
|
+
"Returns nil."
|
32
|
+
false
|
33
|
+
}
|
34
|
+
|
35
|
+
def true? {
|
36
|
+
"Returns true."
|
37
|
+
true
|
38
|
+
}
|
39
|
+
|
40
|
+
def not {
|
41
|
+
false
|
42
|
+
}
|
43
|
+
}
|
data/lib/tuple.fy
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
class Tuple {
|
2
|
+
"""
|
3
|
+
Tuples are fixed-size containers providing index-based access to its
|
4
|
+
elements.
|
5
|
+
"""
|
6
|
+
|
7
|
+
include: FancyEnumerable
|
8
|
+
|
9
|
+
def [] idx {
|
10
|
+
"""
|
11
|
+
Forwards to @Tuple#at:@.
|
12
|
+
"""
|
13
|
+
|
14
|
+
at: idx
|
15
|
+
}
|
16
|
+
|
17
|
+
def each: block {
|
18
|
+
self size times: |i| {
|
19
|
+
block call: [self at: i]
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
def == other {
|
24
|
+
"""
|
25
|
+
@other Other @Tuple@ to compare @self with.
|
26
|
+
@return @true, if tuples are equal element-wise, @false otherwise.
|
27
|
+
|
28
|
+
Compares two @Tuple@s with each other.
|
29
|
+
"""
|
30
|
+
|
31
|
+
if: (other is_a?: Tuple) then: {
|
32
|
+
if: (self size == (other size)) then: {
|
33
|
+
self size times: |i| {
|
34
|
+
unless: (self[i] == (other[i])) do: {
|
35
|
+
return false
|
36
|
+
}
|
37
|
+
}
|
38
|
+
return true
|
39
|
+
}
|
40
|
+
}
|
41
|
+
return false
|
42
|
+
}
|
43
|
+
|
44
|
+
def inspect {
|
45
|
+
str = "("
|
46
|
+
self each: |v| {
|
47
|
+
str = str ++ v
|
48
|
+
} in_between: {
|
49
|
+
str = str ++ ", "
|
50
|
+
}
|
51
|
+
str = str ++ ")"
|
52
|
+
str
|
53
|
+
}
|
54
|
+
|
55
|
+
def Tuple === obj {
|
56
|
+
"""
|
57
|
+
Matches @Tuple@ class against an object.
|
58
|
+
If the given object is a Tuple instance, return a Tuple object.
|
59
|
+
|
60
|
+
@obj Object to be matched against
|
61
|
+
@return Tuple instance containing the values of @obj to be used in pattern matching.
|
62
|
+
"""
|
63
|
+
|
64
|
+
if: (obj is_a?: Tuple) then: {
|
65
|
+
[obj] + (obj map: 'identity)
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
data/lib/version.fy
ADDED
data/tests/argv.fy
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
FancySpec describe: "ARGV & predefined values" with: {
|
2
|
+
it: "should have ARGV correctly defined" when: {
|
3
|
+
ARGV empty? should_not == true
|
4
|
+
}
|
5
|
+
|
6
|
+
it: "should have a __FILE__ variable defined" when: {
|
7
|
+
__FILE__ should_not == nil
|
8
|
+
}
|
9
|
+
|
10
|
+
it: "should have the __FILE__ value be an element in ARGV" when: {
|
11
|
+
ARGV any?: |a| { File basename(a) == (File basename(__FILE__)) } . should == true
|
12
|
+
}
|
13
|
+
}
|
data/tests/array.fy
ADDED
@@ -0,0 +1,343 @@
|
|
1
|
+
FancySpec describe: Array with: {
|
2
|
+
it: "should contain three number values after adding them" for: '<< when: {
|
3
|
+
arr = []
|
4
|
+
arr << 1
|
5
|
+
arr << 2
|
6
|
+
arr << 3
|
7
|
+
arr should == [1,2,3]
|
8
|
+
arr size should == 3
|
9
|
+
}
|
10
|
+
|
11
|
+
it: "should iterate over all elements, calling a block" for: 'each: when: {
|
12
|
+
sum = 0
|
13
|
+
retval = [1,2,3,4,5] each: |x| { sum = sum + x }
|
14
|
+
retval should == sum
|
15
|
+
sum should == ([1,2,3,4,5] sum)
|
16
|
+
}
|
17
|
+
|
18
|
+
it: "should be empty after clearing it" for: 'clear when: {
|
19
|
+
arr = [1,2,3]
|
20
|
+
arr size should == 3
|
21
|
+
arr should == [1,2,3]
|
22
|
+
arr clear
|
23
|
+
arr size should == 0
|
24
|
+
arr should == []
|
25
|
+
}
|
26
|
+
|
27
|
+
it: "should be true for empty? when it's empty" for: 'empty? when: {
|
28
|
+
[] empty? should == true
|
29
|
+
[1] empty? should == false
|
30
|
+
[1,2] empty? should == false
|
31
|
+
[1,2,3] empty? should == false
|
32
|
+
}
|
33
|
+
|
34
|
+
it: "should be an empty array after initialization" for: 'new when: {
|
35
|
+
arr = Array new
|
36
|
+
arr size should == 0
|
37
|
+
}
|
38
|
+
|
39
|
+
it: "should return the correct value via index access" for: 'at: when: {
|
40
|
+
arr = ['a, 10, "hello, world"]
|
41
|
+
arr at: 2 . should == "hello, world"
|
42
|
+
arr at: 1 . should == 10
|
43
|
+
arr at: 0 . should == 'a
|
44
|
+
}
|
45
|
+
|
46
|
+
it: "should NOT include the items" for: "includes?:" when: {
|
47
|
+
arr = ['a, 10, "hello, world"]
|
48
|
+
arr includes?: "hello" . should == false
|
49
|
+
arr includes?: 11 . should == false
|
50
|
+
arr includes?: 'b . should == false
|
51
|
+
}
|
52
|
+
|
53
|
+
it: "should include the items" for: 'includes?: when: {
|
54
|
+
arr = ['a, 10, "hello, world"]
|
55
|
+
arr includes?: "hello, world" . should == true
|
56
|
+
arr includes?: 10 . should == true
|
57
|
+
arr includes?: 'a . should == true
|
58
|
+
}
|
59
|
+
|
60
|
+
it: "should return the correct index (or nil) for an element" for: 'index: when: {
|
61
|
+
arr = [1, 2, 'a, 3, 4]
|
62
|
+
arr index: 1 . should == 0
|
63
|
+
arr index: 2 . should == 1
|
64
|
+
arr index: 'a . should == 2
|
65
|
+
arr index: 3 . should == 3
|
66
|
+
arr index: 4 . should == 4
|
67
|
+
arr index: 'foo . should == nil
|
68
|
+
}
|
69
|
+
|
70
|
+
it: "should return an Array of all its indices" for: 'indices when: {
|
71
|
+
['foo, 'bar, 'baz] indices should == [0,1,2]
|
72
|
+
[] indices should == []
|
73
|
+
['foo] indices should == [0]
|
74
|
+
}
|
75
|
+
|
76
|
+
it: "should return all indices for an element as an Array" for: 'indices: when: {
|
77
|
+
arr = [1, 2, 'a, 3, 2, 'a]
|
78
|
+
arr indices_of: 1 . should == [0]
|
79
|
+
arr indices_of: 2 . should == [1, 4]
|
80
|
+
arr indices_of: 'a . should == [2, 5]
|
81
|
+
arr indices_of: 3. should == [3]
|
82
|
+
arr indices_of: 'foo . should == []
|
83
|
+
}
|
84
|
+
|
85
|
+
it: "should find the value" for: 'find: when: {
|
86
|
+
arr = ['foo, "bar", 'baz, 1234]
|
87
|
+
|
88
|
+
arr find: "bar" . should == "bar"
|
89
|
+
|
90
|
+
arr find: |x| {
|
91
|
+
x is_a?: String . if_true: {
|
92
|
+
x from: 0 to: 1 == "ba"
|
93
|
+
}
|
94
|
+
} . should == "bar"
|
95
|
+
|
96
|
+
arr find: "foo" . should == nil
|
97
|
+
}
|
98
|
+
|
99
|
+
it: "should NOT find the value" for: 'find: when: {
|
100
|
+
arr = ['foo, "bar", 'baz, 1234]
|
101
|
+
|
102
|
+
arr find: "ba" . should == nil
|
103
|
+
|
104
|
+
arr find: |x| {
|
105
|
+
x is_a?: String . if_true: {
|
106
|
+
x from: 0 to: 1 == "aa"
|
107
|
+
}
|
108
|
+
} . should == nil
|
109
|
+
|
110
|
+
arr find: "foobar" . should == nil
|
111
|
+
}
|
112
|
+
|
113
|
+
it: "should find the value via a block" for: 'find_by: when: {
|
114
|
+
arr = [1, 2, 'foo, "yo", nil, true]
|
115
|
+
arr find_by: |x| { x is_a?: String } . should == "yo"
|
116
|
+
arr find_by: |x| { x is_a?: Block } . should == nil
|
117
|
+
}
|
118
|
+
|
119
|
+
it: "should return the last element" for: 'last when: {
|
120
|
+
arr = [1, 2, 3, 'foo, "bar"]
|
121
|
+
arr last should == "bar"
|
122
|
+
(arr last == 'foo) should == false
|
123
|
+
}
|
124
|
+
|
125
|
+
it: "should return the last n element" for: 'last: when: {
|
126
|
+
arr = [1, 2, 3, 'foo, "bar"]
|
127
|
+
arr last: 1 . should == [arr last]
|
128
|
+
arr last: 2 . should == ['foo, "bar"]
|
129
|
+
arr last: 3 . should == [3, 'foo, "bar"]
|
130
|
+
arr last: 4 . should == [2, 3, 'foo, "bar"]
|
131
|
+
arr last: 5 . should == [1, 2, 3, 'foo, "bar"]
|
132
|
+
arr last: (arr size) . should == arr
|
133
|
+
arr last: (arr size + 1) . should == arr
|
134
|
+
}
|
135
|
+
|
136
|
+
it: "should return an array containing the values at the given indices" for: 'values_at: when: {
|
137
|
+
arr = [1, 2, 3, 'foo, "bar"]
|
138
|
+
arr values_at: [1, 3, 4, 10] . should == [2, 'foo, "bar", nil]
|
139
|
+
}
|
140
|
+
|
141
|
+
it: "should return unique values only" for: 'uniq when: {
|
142
|
+
arr = ['foo, 'bar, "baz", 'foo, "baz", "hello", 1, 0, 0, 1, 'bar, 'foo, "hello"]
|
143
|
+
arr uniq should == ['foo, 'bar, "baz", "hello", 1, 0]
|
144
|
+
}
|
145
|
+
|
146
|
+
it: "should prepend self to another array" for: '>> when: {
|
147
|
+
arr1 = ['foo, 'bar, 'baz]
|
148
|
+
arr2 = [1, 2, 3]
|
149
|
+
(arr1 >> arr2) should == ['foo, 'bar, 'baz, 1, 2, 3]
|
150
|
+
}
|
151
|
+
|
152
|
+
it: "should get an element by the []-operator" for: "[]" when: {
|
153
|
+
arr = ['foo, 'bar, 'baz]
|
154
|
+
arr[0] should == 'foo
|
155
|
+
arr[1] should == 'bar
|
156
|
+
arr[2] should == 'baz
|
157
|
+
}
|
158
|
+
|
159
|
+
it: "should get a sub-array by the []-operator" for: "[]" when: {
|
160
|
+
arr = ['foo, 'bar, 'baz]
|
161
|
+
arr[[0,2]] should == arr
|
162
|
+
arr[[0,1]] should == ['foo, 'bar]
|
163
|
+
arr[[0,1]] should == (arr from: 0 to: 1)
|
164
|
+
arr[[0,0]] should == [arr[0]]
|
165
|
+
arr[[1,1]] should == [arr[1]]
|
166
|
+
arr[[2,2]] should == [arr[2]]
|
167
|
+
arr[[0,-1]] should == arr
|
168
|
+
arr[[-1,-1]] should == [arr last]
|
169
|
+
arr[[-2,-1]] should == ['bar, 'baz]
|
170
|
+
arr[[-2,-1]] should == (arr last: 2)
|
171
|
+
}
|
172
|
+
|
173
|
+
it: "should join all elements with a string to a new string" for: 'join: when: {
|
174
|
+
arr = ['foo, 'bar, 'baz]
|
175
|
+
arr join: "," . should == "foo,bar,baz"
|
176
|
+
}
|
177
|
+
|
178
|
+
it: "should join all elements with the empty string to a new string" for: 'join when: {
|
179
|
+
arr = ['foo, 'bar, 'baz]
|
180
|
+
arr join should == "foobarbaz"
|
181
|
+
}
|
182
|
+
|
183
|
+
it: "should remove an element at a given index" for: 'remove_at: when: {
|
184
|
+
arr = [1, 'foo, 2, 'bar, 3, 'baz]
|
185
|
+
# remove_at: returns the removed element
|
186
|
+
arr remove_at: 1 . should == 'foo
|
187
|
+
arr should == [1, 2, 'bar, 3, 'baz]
|
188
|
+
arr remove_at: 3
|
189
|
+
arr should == [1, 2, 'bar, 'baz]
|
190
|
+
arr remove_at: [2, 3]
|
191
|
+
arr should == [1, 2]
|
192
|
+
arr = [1, 'hello, 2, 'world]
|
193
|
+
# remove_at: returns the removed elements as an array
|
194
|
+
# if it was passed an array of indexes
|
195
|
+
arr remove_at: [0, 2, 3] . should == [1, 2, 'world]
|
196
|
+
arr should == ['hello]
|
197
|
+
}
|
198
|
+
|
199
|
+
it: "should remove all occurances of a given object in-place" for: 'remove: when: {
|
200
|
+
arr = [1, 2, 'foo, 3, 'foo, 2, 4]
|
201
|
+
arr remove: 2
|
202
|
+
arr should == [1, 'foo, 3, 'foo, 4]
|
203
|
+
arr remove: 'foo
|
204
|
+
arr should == [1, 3, 4]
|
205
|
+
}
|
206
|
+
|
207
|
+
it: "should remove all elements with the given Array of indices" for: 'remove_at: when: {
|
208
|
+
arr = [1, 2, 'foo, 3, 'foo, 2, 4]
|
209
|
+
arr remove_at: [0, 2, 4]
|
210
|
+
arr should == [2, 3, 2, 4]
|
211
|
+
}
|
212
|
+
|
213
|
+
it: "should remove all elements that meet a given condition block" for: 'remove_if: when: {
|
214
|
+
arr = [1, 2, 3, 2, 5, 4]
|
215
|
+
arr remove_if: |x| { x < 3 }
|
216
|
+
arr should == [3, 5, 4]
|
217
|
+
}
|
218
|
+
|
219
|
+
it: "should remove all nil-value entries when calling compact" for: 'compact when: {
|
220
|
+
['foo, nil, 'bar, nil, 'baz] compact should == ['foo, 'bar, 'baz]
|
221
|
+
[] compact should == []
|
222
|
+
[nil] compact should == []
|
223
|
+
['foo] compact should == ['foo]
|
224
|
+
}
|
225
|
+
|
226
|
+
it: "should remove all nil-value entries in place when calling compact!" for: 'compact! when: {
|
227
|
+
arr = ['foo, nil, 'bar, nil, 'baz]
|
228
|
+
arr compact! should == ['foo, 'bar, 'baz]
|
229
|
+
arr should == ['foo, 'bar, 'baz]
|
230
|
+
[] compact! should == []
|
231
|
+
[nil] compact! should == []
|
232
|
+
['foo] compact! should == ['foo]
|
233
|
+
}
|
234
|
+
|
235
|
+
it: "should remove all values that meet a condition" for: 'reject!: when: {
|
236
|
+
arr = ['foo, 'bar, 1, 2, 'baz, "hello"]
|
237
|
+
arr reject!: |x| { x is_a?: String } . should == ['foo, 'bar, 1, 2, 'baz]
|
238
|
+
arr should == ['foo, 'bar, 1, 2, 'baz]
|
239
|
+
arr reject!: |x| { x is_a?: Fixnum }
|
240
|
+
arr should == ['foo, 'bar, 'baz]
|
241
|
+
}
|
242
|
+
|
243
|
+
it: "should remove all values that don't meet a condition" for: 'select!: when: {
|
244
|
+
arr = ['foo, 'bar, 1, 2, 'baz, "hello"]
|
245
|
+
arr select!: |x| { x is_a?: Fixnum }
|
246
|
+
arr should == [1, 2]
|
247
|
+
}
|
248
|
+
|
249
|
+
it: "should return a new Array with all elements that meet a given condition" for: 'select: when: {
|
250
|
+
arr = [1, 2, "foo", 'bar, 120]
|
251
|
+
arr select: |x| { x is_a?: Fixnum } . should == [1,2,120]
|
252
|
+
arr should == [1, 2, "foo", 'bar, 120] # select: is non-destructive
|
253
|
+
}
|
254
|
+
|
255
|
+
it: "should print the maximum value in the list" for: 'max when: {
|
256
|
+
[1,2,3,4] max should == 4
|
257
|
+
[1,5,-3,2,6,-4,-2] max should == 6
|
258
|
+
}
|
259
|
+
|
260
|
+
it: "should print the minimum value in the list" for: 'min when: {
|
261
|
+
[1,2,3,4] min should == 1
|
262
|
+
[1,5,-3,2,6,-4,-2] min should == -4
|
263
|
+
}
|
264
|
+
|
265
|
+
it: "should return an Array containing the elements n times." for: '* when: {
|
266
|
+
[1,2,3,4,5] * 2 should == [1,2,3,4,5,1,2,3,4,5]
|
267
|
+
[1,2,3] * 2 should == ([1,2,3] + [1,2,3])
|
268
|
+
['a,'b,'c] * 4 should == ['a,'b,'c, 'a,'b,'c, 'a,'b,'c, 'a,'b,'c]
|
269
|
+
}
|
270
|
+
|
271
|
+
it: "should return the concatenation of two Arrays" for: '+ when: {
|
272
|
+
([1,2,3,4] + [-1,-2,-3,-4]) should == [1,2,3,4,-1,-2,-3,-4]
|
273
|
+
}
|
274
|
+
|
275
|
+
it: "should return true for all elements" for: 'all?: when: {
|
276
|
+
[1,2,3,4] all?: |x| { x < 5 } . should == true
|
277
|
+
[1,2,3,4] all?: |x| { x > 0 } . should == true
|
278
|
+
[1,2,3,4] all?: |x| { x > 4 } . should == false
|
279
|
+
}
|
280
|
+
|
281
|
+
it: "should return true for any elements" for: 'any?: when: {
|
282
|
+
[1,2,3,4] any?: |x| { x > 3 } . should == true
|
283
|
+
[1,2,3,4] any?: |x| { x < 4 } . should == true
|
284
|
+
[1,2,3,4] any?: |x| { x > 4 } . should == false
|
285
|
+
}
|
286
|
+
|
287
|
+
it: "should be selected from it with each index" for: 'select_with_index: when: {
|
288
|
+
["yooo",2,3,1,'foo,"bar"] select_with_index: |x i| { x is_a?: Fixnum } . should == [[2,1], [3,2], [1,3]]
|
289
|
+
}
|
290
|
+
|
291
|
+
it: "should return its remaining (all but the first) elements as a new Array" for: 'rest when: {
|
292
|
+
[1,2,3,4] rest should == [2,3,4]
|
293
|
+
[] rest should == []
|
294
|
+
100 upto: 1000 . rest should == (101 upto: 1000)
|
295
|
+
}
|
296
|
+
|
297
|
+
it: "should return itself as a string" for: 'to_s when: {
|
298
|
+
[1,2,3] to_s should == "123"
|
299
|
+
}
|
300
|
+
|
301
|
+
it: "should call a given block between calling the each block" for: 'each:in_between: when: {
|
302
|
+
arr = []
|
303
|
+
[1,2,3] each: |x| { arr << x } in_between: { arr << "-" }
|
304
|
+
arr should == [1, "-", 2, "-", 3]
|
305
|
+
|
306
|
+
str = ""
|
307
|
+
['foo, 'bar, 'baz] each: |x| { str = str ++ (x to_s) } in_between: { str = str ++ " " }
|
308
|
+
str should == "foo bar baz"
|
309
|
+
}
|
310
|
+
|
311
|
+
it: "should return the reduced value for a given block and initial value" for: 'reduce:init_val: when: {
|
312
|
+
arr = 1 upto: 10
|
313
|
+
arr sum should == (arr reduce: '+ init_val: 0)
|
314
|
+
arr product should == (arr reduce: '* init_val: 1)
|
315
|
+
arr to_s should == (arr reduce: '++ init_val: "")
|
316
|
+
}
|
317
|
+
|
318
|
+
it: "should return the reverse of itself" for: 'reverse when: {
|
319
|
+
[1,2,3] reverse should == [3,2,1]
|
320
|
+
1 upto: 10 . reverse should == (10 downto: 1)
|
321
|
+
}
|
322
|
+
|
323
|
+
it: "should inverse in-place" for: 'reverse! when: {
|
324
|
+
arr = [1,2,3]
|
325
|
+
arr reverse! should == [3,2,1]
|
326
|
+
arr should == [3,2,1]
|
327
|
+
}
|
328
|
+
|
329
|
+
it: "should take elements from itself as long a block yields true" for: 'take_while: when: {
|
330
|
+
1 upto: 15 . take_while: |x| { x < 10 } . should == (1 upto: 9)
|
331
|
+
}
|
332
|
+
|
333
|
+
|
334
|
+
it: "should drop elements from itself as long a block yields true" for: 'drop_while: when: {
|
335
|
+
1 upto: 15 . drop_while: |x| { x < 10 } . should == (10 upto: 15)
|
336
|
+
}
|
337
|
+
|
338
|
+
it: "should partition an array via a given block" for: 'partition_by: when: {
|
339
|
+
arr = [1,2,2,3,3,3,4,4,4,4,5]
|
340
|
+
arr partition_by: 'identity . should == [[1], [2,2], [3,3,3], [4,4,4,4], [5]]
|
341
|
+
arr partition_by: @{== 2} . should == [[1], [2,2], [3,3,3,4,4,4,4,5]]
|
342
|
+
}
|
343
|
+
}
|