summaryrefslogtreecommitdiff
path: root/tests/examplefiles/test.cr
diff options
context:
space:
mode:
Diffstat (limited to 'tests/examplefiles/test.cr')
-rw-r--r--tests/examplefiles/test.cr2871
1 files changed, 0 insertions, 2871 deletions
diff --git a/tests/examplefiles/test.cr b/tests/examplefiles/test.cr
deleted file mode 100644
index 028ff6f3..00000000
--- a/tests/examplefiles/test.cr
+++ /dev/null
@@ -1,2871 +0,0 @@
-# Examples taken from http://crystal-lang.org/docs/
-# Copyright 2012-2016 Manas Technology Solutions.
-
-
-require "http/server"
-
-server = HTTP::Server.new(8080) do |context|
- context.response.content_type = "text/plain"
- context.response.print "Hello world! The time is #{Time.now}"
-end
-
-puts "Listening on http://0.0.0.0:8080"
-server.listen
-
-
-module HTTP
- class RequestHandler
- end
-end
-
-alias NumericValue = Float32 | Float64 | Int32 | Int64
-
-enum Time::DayOfWeek
-end
-
-
-$global_greeting = "Hello world"
-
-class Greeting
- @@default_greeting = "Hello world"
-
- def initialize(@custom_greeting = nil)
- end
-
- def print_greeting
- greeting = @custom_greeting || @@default_greeting
- puts greeting
- end
-end
-
-
-LUCKY_NUMBERS = [3, 7, 11]
-DOCUMENTATION_URL = "http://crystal-lang.org/docs"
-
-
-module Scorecard
- class Parser
- def parse(score_text)
- begin
- score_text.scan(SCORE_PATTERN) do |match|
- handle_match(match)
- end
- rescue err : ParseError
- # handle error ...
- end
- end
- end
-end
-
-
-module Money
- CURRENCIES = {
- "EUR" => 1.0,
- "ARS" => 10.55,
- "USD" => 1.12,
- "JPY" => 134.15,
- }
-
- class Amount
- getter :currency, :value
-
- def initialize(@currency, @value)
- end
- end
-
- class CurrencyConversion
- def initialize(@amount, @target_currency)
- end
-
- def amount
- # implement conversion ...
- end
- end
-end
-
-
-i = 0
-while i < 10
- proc = ->(x : Int32) do
- spawn do
- puts(x)
- end
- end
- proc.call(i)
- i += 1
-end
-
-Fiber.yield
-
-
-# A buffered channel of capacity 2
-channel = Channel(Int32).new(2)
-
-spawn do
- channel.send(1)
- channel.send(2)
- channel.send(3)
-end
-
-3.times do |i|
- puts channel.receive
-end
-
-
-class MyDictionary(K, V)
-end
-
-
-MyBox.new(1) #:: MyBox(Int32)
-MyBox.new("hello") #:: MyBox(String)
-
-
-module Moo(T)
- def t
- T
- end
-end
-
-class Foo(U)
- include Moo(U)
-
- def initialize(@value : U)
- end
-end
-
-foo = Foo.new(1)
-foo.t # Int32
-
-
-class Parent(T)
-end
-
-class Int32Child < Parent(Int32)
-end
-
-class GenericChild(T) < Parent(T)
-end
-
-
-class Person
-end
-
-
-a = 1
-ptr = pointerof(a)
-ptr[100_000] = 2 # undefined behaviour, probably a segmentation fault
-
-
-alias Int32OrString = Int32 | String
-
-
-alias Int32OrNil = Int32?
-
-
-alias Int32OrNil_ = Int32 | ::Nil
-
-
-alias Int32Ptr = Int32*
-
-
-alias Int32Ptr_ = Pointer(Int32)
-
-
-alias Int32_8 = Int32[8]
-
-
-alias Int32_8_ = StaticArray(Int32, 8)
-
-
-alias Int32StringTuple = {Int32, String}
-
-
-alias Int32StringTuple_ = Tuple(Int32, String)
-
-
-alias Int32ToString = Int32 -> String
-
-
-alias Int32ToString_ = Proc(Int32, String)
-
-
-alias ProcThatReturnsInt32 = -> Int32
-
-
-alias Int32AndCharToString = Int32, Char -> String
-
-
-alias ComplexProc = (Int32 -> Int32) -> String
-
-
-def foo(x : Int32)
- "instance"
-end
-
-def foo(x : Int32.class)
- "class"
-end
-
-foo 1 # "instance"
-foo Int32 # "class"
-
-
-class Parent
-end
-
-class Child1 < Parent
-end
-
-class Child2 < Parent
-end
-
-ary = [] of Parent.class
-ary << Child1
-ary << Child2
-
-
-# Same as not specifying a restriction, not very useful
-def foo(x : _)
-end
-
-# A bit more useful: any two arguments Proc that returns an Int32:
-def foo(x : _, _ -> Int32)
-end
-
-
-#alias SameAsInt32 = typeof(2)
-#alias Int32OrString_ = typeof(1, "a")
-
-
-class Person
- def initialize(name)
- @name = name
- @age = 0
- end
-
- def name
- @name
- end
-
- def age
- @age
- end
-end
-
-
-john = Person.new "John"
-peter = Person.new "Peter"
-
-john.name #=> "John"
-john.age #=> 0
-
-peter.name #=> "Peter"
-
-
-class Person
- def self.new(name)
- instance = Person.allocate
- instance.initialize(name)
- instance
- end
- end
-
-
-if a.is_a?(String)
- # here a is a String
-end
-
-if b.is_a?(Number)
- # here b is a Number
-end
-
-
-a = some_condition ? 1 : "hello"
-# a : Int32 | String
-
-if a.is_a?(Number)
- # a : Int32
-else
- # a : String
-end
-
-
-if a.is_a?(String) && b.is_a?(Number)
- # here a is a String and b is a Number
-end
-
-
-a.+(b)
-
-
-struct Vector2
- getter x, y
-
- def initialize(@x, @y)
- end
-
- def +(other)
- Vector2.new(x + other.x, y + other.y)
- end
-end
-
-v1 = Vector2.new(1, 2)
-v2 = Vector2.new(3, 4)
-v1 + v2 #=> Vector2(@x=4, @y=6)
-
-
-
-
-struct Vector2
- def -
- Vector2.new(-x, -y)
- end
-end
-
-v1 = Vector2.new(1, 2)
--v1 #=> Vector2(@x=-1, @y=-2)
-
-
-
-
-
-class MyArray
- def [](index)
- # ...
- end
-
- def [](index1, index2, index3)
- # ...
- end
-
- def []=(index, value)
- # ...
- end
-end
-
-array = MyArray.new
-
-array[1] # invokes the first method
-array[1, 2, 3] # invokes the second method
-array[1] = 2 # invokes the third method
-
-array.[](1) # invokes the first method
-array.[](1, 2, 3) # invokes the second method
-array.[]=(1, 2) # invokes the third method
-
-
-raise "OH NO!"
-raise Exception.new("Some error")
-
-
-class MyException < Exception
-end
-
-
-begin
- raise MyException.new("OH NO!")
-rescue ex : MyException
- puts "Rescued MyException: #{ex.message}"
-end
-
-
-begin
- # ...
-rescue ex : MyException | MyOtherException
- # only MyException or MyOtherException
-rescue
- # any other kind of exception
-ensure
- puts "Cleanup..."
-end
-
-
-def some_method
- something_dangerous
-rescue
- # execute if an exception is raised
-end
-
-
-array = [1, 2, 3]
-array[4] # raises because of IndexError
-array[4]? # returns nil because of index out of bounds
-
-
-def some_proc(&block : Int32 -> Int32)
- block
-end
-
-x = 0
-proc = ->(i : Int32) { x += i }
-proc = some_proc(&proc)
-proc.call(1) #=> 1
-proc.call(10) #=> 11
-x #=> 11
-
-
-def add(x, y)
- x + y
-end
-
-adder = ->add(Int32, Int32)
-adder.call(1, 2) #=> 3
-
-
-module Curses
- class Window
- end
-end
-
-Curses::Window.new
-
-
-module ItemsSize
- def size
- items.size
- end
-end
-
-class Items
- include ItemsSize
-
- def items
- [1, 2, 3]
- end
-end
-
-items = Items.new
-items.size #=> 3
-
-
-module Base64
- extend self
-
- def encode64(string)
- # ...
- end
-
- def decode64(string)
- # ...
- end
-end
-
-Base64.encode64 "hello" #=> "aGVsbG8="
-
-
-if some_condition
- a = 1
-else
- a = "hello"
-end
-
-a_as_int = a as Int32
-a_as_int.abs # works, compiler knows that a_as_int is Int32
-
-
-ptr = Pointer(Int32).malloc(1)
-ptr as Int8* #:: Pointer(Int8)
-
-
-array = [1, 2, 3]
-
-# object_id returns the address of an object in memory,
-# so we create a pointer with that address
-ptr = Pointer(Void).new(array.object_id)
-
-# Now we cast that pointer to the same type, and
-# we should get the same value
-array2 = ptr as Array(Int32)
-array2.same?(array) #=> true
-
-
-a = 1
-b = a as Int32 | Float64
-b #:: Int32 | Float64
-
-
-ary = [1, 2, 3]
-
-# We want to create an array 1, 2, 3 of Int32 | Float64
-ary2 = ary.map { |x| x as Int32 | Float64 }
-
-ary2 #:: Array(Int32 | Float64)
-ary2 << 1.5 # OK
-
-
-class Person
- def initialize(@name)
- end
-
- def name
- @name
- end
-end
-
-a = [] of Person
-x = a.map { |f| f.name } # Error: can't infer block return type
-
-
-a = [] of Person
-x = a.map { |f| f.name as String } # OK
-
-
-Person.new "John"
-
-a = [] of Person
-x = a.map { |f| f.name } # OK
-
-
-loop do
- do_something
- break if some_condition
-end
-
-
-class Point
- def initialize(@x, @y)
- end
-end
-
-Point.new 1, 2
-
-# 2 x Int32 = 2 x 4 = 8
-instance_sizeof(Point) #=> 12
-
-
-a = 1
-while a < 5
- a += 1
- if a == 3
- next
- end
- puts a
-end
-# The above prints the numbers 2, 4 and 5
-
-
-lib C
- # In C: double cos(double x)
- fun cos(value : Float64) : Float64
-
- fun getch : Int32
-
- fun srand(seed : UInt32)
-
- fun exit(status : Int32) : NoReturn
-
- fun printf(format : UInt8*, ...) : Int32
-end
-
-C.cos(1.5) #=> 0.0707372
-C.srand(1_u32)
-
-a = 1
-b = 2
-C.printf "%d + %d = %d\n", a, b, a + b
-
-
-lib LibSDL
- fun init = SDL_Init(flags : UInt32) : Int32
-end
-
-lib LLVMIntrinsics
- fun ceil_f32 = "llvm.ceil.f32"(value : Float32) : Float32
-end
-
-lib MyLib
- fun my_fun(some_size : LibC::SizeT)
-end
-
-@[Link("pcre")]
-lib LibPCRE
-end
-
-
-lib C
- ifdef x86_64
- alias SizeT = UInt64
- else
- alias SizeT = UInt32
- end
-
- fun memcmp(p1 : Void*, p2 : Void*, size : C::SizeT) : Int32
-end
-
-
-lib X
- enum SomeEnum
- Ten = 10
- Twenty = 10 * 2
- ThirtyTwo = 1 << 5
- end
-end
-
-
-lib X
- enum SomeEnum
- A = 1_u32
- end
-end
-
-
-X::SomeEnum::Zero #=> 0_i8
-X::SomeEnum::Two #=> 2_i8
-
-
-lib X
- fun callback(f : Int32 -> Int32)
-end
-
-
-f = ->(x : Int32) { x + 1 }
-X.callback(f)
-
-
-X.callback ->(x) { x + 1 }
-
-
-X.callback nil
-
-
-lib LibFoo
- fun store_callback(callback : ->)
- fun execute_callback
-end
-
-LibFoo.store_callback ->{ raise "OH NO!" }
-LibFoo.execute_callback
-
-
-lib LibFoo
- fun store_callback(callback : ->)
-
- @[Raises]
- fun execute_callback
-end
-
-
-@[Link("pcre")]
-lib PCRE
- INFO_CAPTURECOUNT = 2
-end
-
-PCRE::INFO_CAPTURECOUNT #=> 2
-
-
-lib U
- # In C:
- #
- # union IntOrFloat {
- # int some_int;
- # double some_float;
- # };
- union IntOrFloat
- some_int : Int32
- some_float : Float64
- end
-end
-
-
-value = U::IntOrFloat.new
-
-
-value = uninitialized U::IntOrFlaot
-value.some_int #=> some garbage value
-
-
-value = U::IntOrFloat.new
-value.some_int = 1
-value.some_int #=> 1
-value.some_float #=> 4.94066e-324
-
-
-def change_it(value)
- value.some_int = 1
-end
-
-value = U::IntOrFloat.new
-change_it value
-value.some_int #=> 0
-
-
-lib C
- # In C:
- #
- # struct TimeZone {
- # int minutes_west;
- # int dst_time;
- # };
- struct TimeZone
- minutes_west : Int32
- dst_time : Int32
- end
-end
-
-
-lib C
- # This is a forward declaration
- struct Node
- end
-
- struct Node
- node : Node*
- end
-end
-
-
-tz = C::TimeZone.new
-
-
-tz = uninitialized C::TimeZone
-tz.minutes_west #=> some garbage value
-
-
-tz = C::TimeZone.new
-tz.minutes_west = 1
-tz.minutes_west #=> 1
-
-
-tz = C::TimeZone.new minutes_west: 1, dst_time: 2
-tz.minutes_west #=> 1
-tz.dst_time #=> 2
-
-
-def change_it(tz)
- tz.minutes_west = 1
-end
-
-tz = C::TimeZone.new
-change_it tz
-tz.minutes_west #=> 0
-
-
-lib C
- $errno : Int32
-end
-
-
-C.errno #=> some value
-C.errno = 0
-C.errno #=> 0
-
-
-lib C
- @[ThreadLocal]
- $errno : Int32
-end
-
-
-lib C
- fun waitpid(pid : Int32, status_ptr : Int32*, options : Int32) : Int32
-end
-
-
-status_ptr = uninitialized Int32
-
-C.waitpid(pid, pointerof(status_ptr), options)
-
-
-C.waitpid(pid, out status_ptr, options)
-
-
-lib X
- type CInt = Int32
-end
-
-
-ifdef x86_64
- # some specific code for 64 bits platforms
-else
- # some specific code for non-64 bits platforms
-end
-
-
-ifdef linux && x86_64
- # some specific code for linux 64 bits
-end
-
-
-lib C
- ifdef linux
- struct SomeStruct
- some_field : Int32
- end
- else
- struct SomeStruct
- some_field : Int64
- end
- end
-end
-
-
-# Assigns to a local variable
-local = 1
-
-# Assigns to a global variable
-$global = 4
-
-class Testing
- # Assigns to an instance variable
- @instance = 2
-
- # Assigns to a class variable
- @@class = 3
-end
-
-
-local += 1 # same as: local = local + 1
-
-# The above is valid with these operators:
-# +, -, *, /, %, |, &, ^, **, <<, >>
-
-local ||= 1 # same as: local || (local = 1)
-local &&= 1 # same as: local && (local = 1)
-
-
-# A setter
-person.name=("John")
-
-# The above can be written as:
-person.name = "John"
-
-# An indexed assignment
-objects.[]=(2, 3)
-
-# The above can be written as:
-objects[2] = 3
-
-# Not assignment-related, but also syntax sugar:
-objects.[](2, 3)
-
-# The above can be written as:
-objects[2, 3]
-
-
-person.age += 1 # same as: person.age = person.age + 1
-
-person.name ||= "John" # same as: person.name || (person.name = "John")
-person.name &&= "John" # same as: person.name && (person.name = "John")
-
-objects[1] += 2 # same as: objects[1] = objects[1] + 2
-
-objects[1] ||= 2 # same as: objects[1]? || (objects[1] = 2)
-objects[1] &&= 2 # same as: objects[1]? && (objects[1] = 2)
-
-
-alias PInt32 = Pointer(Int32)
-
-ptr = PInt32.malloc(1) # : Pointer(Int32)
-
-
-alias RecArray = Array(Int32) | Array(RecArray)
-
-ary = [] of RecArray
-ary.push [1, 2, 3]
-ary.push ary
-ary #=> [[1, 2, 3], [...]]
-
-
-module Json
- alias Type = Nil |
- Bool |
- Int64 |
- Float64 |
- String |
- Array(Type) |
- Hash(String, Type)
-end
-
-
-a = 1
-if a > 0
- a = 10
-end
-a #=> 10
-
-b = 1
-if b > 2
- b = 10
-else
- b = 20
-end
-b #=> 20
-
-
-if some_condition
- do_something
-elsif some_other_condition
- do_something_else
-else
- do_that
-end
-
-
-a = 1
-if some_condition
- a = "hello"
-else
- a = true
-end
-# a : String | Bool
-
-b = 1
-if some_condition
- b = "hello"
-end
-# b : Int32 | String
-
-if some_condition
- c = 1
-else
- c = "hello"
-end
-# c : Int32 | String
-
-if some_condition
- d = 1
-end
-# d : Int32 | Nil
-
-
-a = 1
-if some_condition
- a = "hello"
- # a : String
- a.size
-end
-# a : String | Int32
-
-
-if some_condition
- e = 1
-else
- e = "hello"
- # e : String
- return
-end
-# e : Int32
-
-
-enum Color : UInt8
- Red # 0
- Green # 1
- Blue = 5 # overwritten to 5
- Yellow # 6 (5 + 1)
-
- def red?
- self == Color::Red
- end
-end
-
-Color::Red.value #:: UInt8
-
-
-@[Flags]
-enum IOMode
- Read # 1
- Write # 2
- Async # 4
-end
-
-
-IOMode::None.value #=> 0
-IOMode::All.value #=> 7
-
-
-puts(Color::Red) # prints "Red"
-puts(IOMode::Write | IOMode::Async) # prints "Write, Async"
-
-
-puts Color.new(1) #=> prints "Green"
-
-
-puts Color.new(10) #=> prints "10"
-
-
-Color::Red.red? #=> true
-Color::Blue.red? #=> false
-
-
-def paint(color : Color)
- case color
- when Color::Red
- # ...
- else
- # Unusual, but still can happen
- raise "unknown color: #{color}"
- end
-end
-
-paint Color::Red
-
-
-def paint(color : Symbol)
- case color
- when :red
- # ...
- else
- raise "unknown color: #{color}"
- end
-end
-
-paint :red
-
-
-name = "Crystal"
-age = 1
-
-
-flower = "Tulip"
-# At this point 'flower' is a String
-
-flower = 1
-# At this point 'flower' is an Int32
-
-
-class Foo
- def finalize
- # Invoked when Foo is garbage-collected
- puts "Bye bye from #{self}!"
- end
-end
-
-# Prints "Bye bye ...!" for ever
-loop do
- Foo.new
-end
-
-
-# Defines a method in the program
-def add(x, y)
- x + y
-end
-
-# Invokes the add method in the program
-add(1, 2) #=> 3
-
-
-def even?(num)
- if num % 2 == 0
- return true
- end
-
- return false
-end
-
-
-def add(x, y)
- x + y
-end
-
-class Foo
- def bar
- # invokes the program's add method
- add(1, 2)
-
- # invokes Foo's baz method
- baz(1, 2)
- end
-
- def baz(x, y)
- x * y
- end
-end
-
-
-def baz(x, y)
- x + y
-end
-
-class Foo
- def bar
- baz(4, 2) #=> 2
- ::baz(4, 2) #=> 6
- end
-
- def baz(x, y)
- x - y
- end
-end
-
-
-x = 1
-
-def add(y)
- x + y # error: undefined local variable or method 'x'
-end
-
-add(2)
-
-
-add 1, 2 # same as add(1, 2)
-
-
-class Counter
- @@instances = 0
-
- def initialize
- @@instances += 1
- end
-
- def self.instances
- @@instances
- end
-end
-
-Counter.instances #=> 0
-Counter.new
-Counter.new
-Counter.new
-Counter.instances #=> 3
-
-
-class Counter
- def self.increment
- @@instances += 1
- end
-end
-
-Counter.increment # Error: undefined method '+' for Nil
-
-
-class Parent
- @@counter = 0
-end
-
-class Child < Parent
- def self.counter
- @@counter
- end
-end
-
-Child.counter #=> nil
-
-
-unless some_condition
- then_expression
-else
- else_expression
-end
-
-# Can also be written as a suffix
-close_door unless door_closed?
-
-
-a = 1
-b = typeof(a) #=> Int32
-
-
-typeof(1, "a", 'a') #=> (Int32 | String | Char)
-
-
-hash = {} of Int32 => String
-another_hash = typeof(hash).new #:: Hash(Int32, String)
-
-
-class Array
- def self.elem_type(typ)
- if typ.is_a?(Array)
- elem_type(typ.first)
- else
- typ
- end
- end
-end
-
-nest = [1, ["b", [:c, ['d']]]]
-flat = Array(typeof(Array.elem_type(nest))).new
-typeof(nest) #=> Array(Int32 | Array(String | Array(Symbol | Array(Char))))
-typeof(flat) #=> Array(String | Int32 | Symbol | Char)
-
-
-a = 2 if some_condition
-
-
-x = 0
-proc = ->{ x += 1; x }
-proc.call #=> 1
-proc.call #=> 2
-x #=> 2
-
-
-def counter
- x = 0
- ->{ x += 1; x }
-end
-
-proc = counter
-proc.call #=> 1
-proc.call #=> 2
-
-
-def foo
- yield
-end
-
-x = 1
-foo do
- x = "hello"
-end
-x # : Int32 | String
-
-
-x = 1
-foo do
- x = "hello"
-end
-x # : Int32 | String
-
-x = 'a'
-x # : Char
-
-
-def capture(&block)
- block
-end
-
-x = 1
-capture { x = "hello" }
-
-x = 'a'
-x # : Int32 | String | Char
-
-
-def capture(&block)
- block
-end
-
-x = 1
-->{ x = "hello" }
-
-x = 'a'
-x # : Int32 | String | Char
-
-
-abstract class Animal
- # Makes this animal talk
- abstract def talk
-end
-
-class Dog < Animal
- def talk
- "Woof!"
- end
-end
-
-class Cat < Animal
- def talk
- "Miau"
- end
-end
-
-class Person
- getter pet
-
- def initialize(@name, @pet)
- end
-end
-
-john = Person.new "John", Dog.new
-peter = Person.new "Peter", Cat.new
-
-
-john.pet.talk #=> "Woof!"
-
-
-a = 1 > 2 ? 3 : 4
-
-# The above is the same as:
-a = if 1 > 2
- 3
- else
- 4
- end
-
-
-def some_method : String
- "hello"
-end
-
-
-PI = 3.14
-
-module Earth
- RADIUS = 6_371_000
-end
-
-PI #=> 3.14
-Earth::RADIUS #=> 6_371_000
-
-
-TEN = begin
- a = 0
- while a < 10
- a += 1
- end
- a
-end
-
-TEN #=> 10
-
-
-class Person
- getter name
-
- def initialize(@name)
- @age = 0
- end
-end
-
-john = Person.new "John"
-john.name #=> "John"
-john.name.size #=> 4
-
-
-one = Person.new 1
-one.name #=> 1
-one.name + 2 #=> 3
-
-
-john = Person.new "John"
-one = Person.new 1
-
-
-john = Person.new "John"
-one = Person.new 1
-
-# Error: undefined method 'size' for Int32
-john.name.size
-
-# Error: no overload matches 'String#+' with types Int32
-john.name + 3
-
-
-john = Person.new "John"
-john.name.size
-one = Person.new 1
-
-
-class Person
- getter name
-
- def initialize(@name)
- @age = 0
- end
-
- def address
- @address
- end
-
- def address=(@address)
- end
-end
-
-john = Person.new "John"
-john.address = "Argentina"
-
-
-# Error: undefined method 'size' for Nil
-john.address.size
-
-
-class Person
- @age = 0
-
- def initialize(@name)
- end
-end
-
-
-class Person
- @age : Int32
-
- def initialize(@name)
- @age = 0
- end
-end
-
-
-a = if 2 > 1
- 3
- else
- 4
- end
-a #=> 3
-
-
-if 1 > 2
-else
- 3
-end
-
-
-def twice(&block)
- yield
- yield
-end
-
-
-twice() do
- puts "Hello!"
-end
-
-twice do
- puts "Hello!"
-end
-
-twice { puts "Hello!" }
-
-
-def twice
- yield 1
- yield 2
-end
-
-twice do |i|
- puts "Got #{i}"
-end
-
-
-twice { |i| puts "Got #{i}" }
-
-
-def many
- yield 1, 2, 3
-end
-
-many do |x, y, z|
- puts x + y + z
-end
-
-# Output: 6
-
-
-def many
- yield 1, 2, 3
-end
-
-many do |x, y|
- puts x + y
-end
-
-# Output: 3
-
-
-def twice
- yield
- yield
-end
-
-twice do |i|
- puts i.inspect
-end
-
-
-def some
- yield 1, 'a'
- yield true, "hello"
- yield 2
-end
-
-some do |first, second|
- # first is Int32 | Bool
- # second is Char | String | Nil
-end
-
-
-method do |argument|
- argument.some_method
-end
-
-
-method(&.some_method)
-
-
-method &.some_method(arg1, arg2)
-
-
-method &.+(2)
-method &.[index]
-
-
-def twice
- v1 = yield 1
- puts v1
-
- v2 = yield 2
- puts v2
-end
-
-twice do |i|
- i + 1
-end
-
-
-ary = [1, 2, 3]
-ary.map { |x| x + 1 } #=> [2, 3, 4]
-ary.select { |x| x % 2 == 1 } #=> [1, 3]
-
-
-def transform(value)
- yield value
-end
-
-transform(1) { |x| x + 1 } #=> 2
-
-
-def thrice
- puts "Before 1"
- yield 1
- puts "Before 2"
- yield 2
- puts "Before 3"
- yield 3
- puts "After 3"
-end
-
-thrice do |i|
- if i == 2
- break
- end
-end
-
-
-def twice
- yield 1
- yield 2
-end
-
-twice { |i| i + 1 } #=> 3
-twice { |i| break "hello" } #=> "hello"
-
-
-value = twice do |i|
- if i == 1
- break "hello"
- end
- i + 1
-end
-value #:: Int32 | String
-
-
-values = twice { break 1, 2 }
-values #=> {1, 2}
-
-
-value = twice { break }
-value #=> nil
-
-
-def twice
- yield 1
- yield 2
-end
-
-twice do |i|
- if i == 1
- puts "Skipping 1"
- next
- end
-
- puts "Got #{i}"
-end
-
-
-
-def twice
- v1 = yield 1
- puts v1
-
- v2 = yield 2
- puts v2
-end
-
-twice do |i|
- if i == 1
- next 10
- end
-
- i + 1
-end
-
-# Output
-# 10
-# 3
-
-
-class Foo
- def one
- 1
- end
-
- def yield_with_self
- with self yield
- end
-
- def yield_normally
- yield
- end
-end
-
-def one
- "one"
-end
-
-Foo.new.yield_with_self { one } # => 1
-Foo.new.yield_normally { one } # => "one"
-
-
-def twice
- yield 1
- yield 2
-end
-
-twice do |i|
- puts "Got: #{i}"
-end
-
-
-i = 1
-puts "Got: #{i}"
-i = 2
-puts "Got: #{i}"
-
-
-3.times do |i|
- puts i
-end
-
-
-struct Int
- def times
- i = 0
- while i < self
- yield i
- i += 1
- end
- end
-end
-
-
-i = 0
-while i < 3
- puts i
- i += 1
-end
-
-
-class Person
- def initialize(@name)
- end
-
- def greet
- puts "Hi, I'm #{@name}"
- end
-end
-
-class Employee < Person
-end
-
-employee = Employee.new "John"
-employee.greet # "Hi, I'm John"
-
-
-class Person
- def initialize(@name)
- end
-end
-
-class Employee < Person
- def initialize(@name, @company_name)
- end
-end
-
-Employee.new "John", "Acme" # OK
-Employee.new "Peter" # Error: wrong number of arguments
- # for 'Employee:Class#new' (1 for 2)
-
-
-class Person
- def greet(msg)
- puts "Hi, #{msg}"
- end
-end
-
-class Employee < Person
- def greet(msg)
- puts "Hello, #{msg}"
- end
-end
-
-p = Person.new
-p.greet "everyone" # "Hi, everyone"
-
-e = Employee.new
-e.greet "everyone" # "Hello, everyone"
-
-
-class Person
- def greet(msg)
- puts "Hi, #{msg}"
- end
-end
-
-class Employee < Person
- def greet(msg : Int32)
- puts "Hi, this is a number: #{msg}"
- end
-end
-
-e = Employee.new
-e.greet "everyone" # "Hi, everyone"
-
-e.greet 1 # "Hi, this is a number: 1"
-
-
-class Person
- def greet(msg)
- puts "Hello, "#{msg}"
- end
-end
-
-class Employee < Person
- def greet(msg)
- super # Same as: super(msg)
- super("another message")
- end
-end
-
-
-def int_to_int(&block : Int32 -> Int32)
- block
-end
-
-proc = int_to_int { |x| x + 1 }
-proc.call(1) #=> 2
-
-
-class Model
- def on_save(&block)
- @on_save_callback = block
- end
-
- def save
- if callback = @on_save_callback
- callback.call
- end
- end
-end
-
-model = Model.new
-model.on_save { puts "Saved!" }
-model.save # prints "Saved!"
-
-
-def some_proc(&block : Int32 ->)
- block
-end
-
-proc = some_proc { |x| x + 1 }
-proc.call(1) # void
-
-
-def some_proc(&block : Int32 -> _)
- block
-end
-
-proc = some_proc { |x| x + 1 }
-proc.call(1) # 2
-
-proc = some_proc { |x| x.to_s }
-proc.call(1) # "1"
-
-
-macro update_x
- x = 1
-end
-
-x = 0
-update_x
-x #=> 1
-
-
-macro dont_update_x
- %x = 1
- puts %x
-end
-
-x = 0
-dont_update_x # outputs 1
-x #=> 0
-
-
-macro fresh_vars_sample(*names)
- # First declare vars
- {% for name, index in names %}
- print "Declaring: ", "%name{index}", '\n'
- %name{index} = {{index}}
- {% end %}
-
- # Then print them
- {% for name, index in names %}
- print "%name{index}: ", %name{index}, '\n'
- {% end %}
-end
-
-fresh_vars_sample a, b, c
-
-# Sample output:
-# Declaring: __temp_255
-# Declaring: __temp_256
-# Declaring: __temp_257
-# __temp_255: 0
-# __temp_256: 1
-# __temp_257: 2
-
-
-class Object
- macro def instance_vars_names : Array(String)
- {{ @type.instance_vars.map &.name.stringify }}
- end
-end
-
-class Person
- def initialize(@name, @age)
- end
-end
-
-person = Person.new "John", 30
-person.instance_vars_names #=> ["name", "age"]
-
-
-class Object
- macro def has_instance_var?(name) : Bool
- # We cannot access name inside the macro expansion here,
- # instead we need to use the macro language to construct an array
- # and do the inclusion check at runtime.
- {{ @type.instance_vars.map &.name.stringify }}.includes? name
- end
-end
-
-person = Person.new "John", 30
-person.has_instance_var?("name") #=> true
-person.has_instance_var?("birthday") #=> false
-
-
-class Parent
- macro inherited
- def {{@type.name.downcase.id}}
- 1
- end
- end
-end
-
-class Child < Parent
-end
-
-Child.new.child #=> 1
-
-
-macro method_missing(name, args, block)
- print "Got ", {{name.id.stringify}}, " with ", {{args.size}}, " arguments", '\n'
-end
-
-foo # Prints: Got foo with 0 arguments
-bar 'a', 'b' # Prints: Got bar with 2 arguments
-
-
-sizeof(Int32) #=> 4
-sizeof(Int64) #=> 8
-
-
-# On a 64 bits machine
-sizeof(Pointer(Int32)) #=> 8
-sizeof(String) #=> 8
-
-
-a = 1
-sizeof(typeof(a)) #=> 4
-
-
-class Foo
- macro emphasize(value)
- "***#{ {{value}} }***"
- end
-
- def yield_with_self
- with self yield
- end
-end
-
-Foo.new.yield_with_self { emphasize(10) } #=> "***10***"
-
-
-# This generates:
-#
-# def :foo
-# 1
-# end
-define_method :foo, 1
-
-
-macro define_method(name, content)
- def {{name.id}}
- {{content}}
- end
-end
-
-# This correctly generates:
-#
-# def foo
-# 1
-# end
-define_method :foo, 1
-
-
-macro define_method(name, content)
- def {{name}}
- {% if content == 1 %}
- "one"
- {% else %}
- {{content}}
- {% end %}
- end
-end
-
-define_method foo, 1
-define_method bar, 2
-
-foo #=> one
-bar #=> 2
-
-
-{% if env("TEST") %}
- puts "We are in test mode"
-{% end %}
-
-
-macro define_dummy_methods(names)
- {% for name, index in names %}
- def {{name.id}}
- {{index}}
- end
- {% end %}
-end
-
-define_dummy_methods [foo, bar, baz]
-
-foo #=> 0
-bar #=> 1
-baz #=> 2
-
-
-macro define_dummy_methods(hash)
- {% for key, value in hash %}
- def {{key.id}}
- {{value}}
- end
- {% end %}
-end
-define_dummy_methods({foo: 10, bar: 20})
-foo #=> 10
-bar #=> 20
-
-
-{% for name, index in ["foo", "bar", "baz"] %}
- def {{name.id}}
- {{index}}
- end
-{% end %}
-
-foo #=> 0
-bar #=> 1
-baz #=> 2
-
-
-macro define_dummy_methods(*names)
- {% for name, index in names %}
- def {{name.id}}
- {{index}}
- end
- {% end %}
-end
-
-define_dummy_methods foo, bar, baz
-
-foo #=> 0
-bar #=> 1
-baz #=> 2
-
-
-macro println(*values)
- print {{*values}}, '\n'
-end
-
-println 1, 2, 3 # outputs 123\n
-
-
-VALUES = [1, 2, 3]
-
-{% for value in VALUES %}
- puts {{value}}
-{% end %}
-
-
-until some_condition
- do_this
-end
-
-# The above is the same as:
-while !some_condition
- do_this
-end
-
-
-a = some_condition ? nil : 3
-# a is Int32 or Nil
-
-if a
- # Since the only way to get here is if a is truthy,
- # a can't be nil. So here a is Int32.
- a.abs
-end
-
-
-if a = some_expression
- # here a is not nil
-end
-
-
-if a && b
- # here both a and b are guaranteed not to be Nil
-end
-
-
-if @a
- # here @a can be nil
-end
-
-
-# First option: assign it to a variable
-if a = @a
- # here a can't be nil
-end
-
-# Second option: use `Object#try` found in the standard library
-@a.try do |a|
- # here a can't be nil
-end
-
-
-if method # first call to a method that can return Int32 or Nil
- # here we know that the first call did not return Nil
- method # second call can still return Int32 or Nil
-end
-
-
-class Person
- def become_older(by = 1)
- @age += by
- end
-end
-
-john = Person.new "John"
-john.age #=> 0
-
-john.become_older
-john.age #=> 1
-
-john.become_older 2
-john.age #=> 3
-
-
-john.become_older by: 5
-
-
-def some_method(x, y = 1, z = 2, w = 3)
- # do something...
-end
-
-some_method 10 # x = 10, y = 1, z = 2, w = 3
-some_method 10, z: 10 # x = 10, y = 1, z = 10, w = 3
-some_method 10, w: 1, y: 2, z: 3 # x = 10, y = 2, z = 3, w = 1
-
-
-case exp
-when value1, value2
- do_something
-when value3
- do_something_else
-else
- do_another_thing
-end
-
-
-case var
-when String
- # var : String
- do_something
-when Int32
- # var : Int32
- do_something_else
-else
- # here var is neither a String nor an Int32
- do_another_thing
-end
-
-
-case num
-when .even?
- do_something
-when .odd?
- do_something_else
-end
-
-
-case
-when cond1, cond2
- do_something
-when cond3
- do_something_else
-end
-
-
-a = 1
-a.responds_to?(:abs) #=> true
-a.responds_to?(:size) #=> false
-
-
-foo_or_bar = /foo|bar/
-heeello = /h(e+)llo/
-integer = /\d+/
-
-
-r = /foo/imx
-
-
-slash = /\//
-
-
-r = %r(regex with slash: /)
-
-
-"hello world"
-
-
-"\"" # double quote
-"\\" # backslash
-"\e" # escape
-"\f" # form feed
-"\n" # newline
-"\r" # carriage return
-"\t" # tab
-"\v" # vertical tab
-
-
-"\101" # == "A"
-"\123" # == "S"
-"\12" # == "\n"
-"\1" # string with one character with code point 1
-
-
-"\u0041" # == "A"
-
-
-"\u{41}" # == "A"
-"\u{1F52E}" # == "🔮"
-
-
-"hello
- world" # same as "hello\n world"
-
-
-"hello " \
-"world, " \
-"no newlines" # same as "hello world, no newlines"
-
-
-"hello \
- world, \
- no newlines" # same as "hello world, no newlines"
-
-
-# Supports double quotes and nested parenthesis
-%(hello ("world")) # same as "hello (\"world\")"
-
-# Supports double quotes and nested brackets
-%[hello ["world"]] # same as "hello [\"world\"]"
-
-# Supports double quotes and nested curlies
-%{hello {"world"}} # same as "hello {\"world\"}"
-
-# Supports double quotes and nested angles
-%<hello <"world">> # same as "hello <\"world\">"
-
-
-<<-XML
-<parent>
- <child />
-</parent>
-XML
-
-
-# Same as "Hello\n world"
-<<-STRING
- Hello
- world
- STRING
-
-# Same as " Hello\n world"
-<<-STRING
- Hello
- world
- STRING
-
-
-a = 1
-b = 2
-"sum = #{a + b}" # "sum = 3"
-
-
-1.0 # Float64
-1.0_f32 # Float32
-1_f32 # Float32
-
-1e10 # Float64
-1.5e10 # Float64
-1.5e-7 # Float64
-
-+1.3 # Float64
--0.5 # Float64
-
-
-1_000_000.111_111 # better than 1000000.111111
-
-
-'a'
-'z'
-'0'
-'_'
-'あ'
-
-
-'\'' # single quote
-'\\' # backslash
-'\e' # escape
-'\f' # form feed
-'\n' # newline
-'\r' # carriage return
-'\t' # tab
-'\v' # vertical tab
-
-
-'\101' # == 'A'
-'\123' # == 'S'
-'\12' # == '\n'
-'\1' # code point 1
-
-
-'\u0041' # == 'A'
-
-
-'\u{41}' # == 'A'
-'\u{1F52E}' # == '🔮'
-
-
-{1 => 2, 3 => 4} # Hash(Int32, Int32)
-{1 => 2, 'a' => 3} # Hash(Int32 | Char, Int32)
-
-
-{} of Int32 => Int32 # same as Hash(Int32, Int32).new
-
-
-{key1: 'a', key2: 'b'} # Hash(Symbol, Char)
-
-
-{"key1": 'a', "key2": 'b'} # Hash(String, Char)
-
-
-MyType{"foo": "bar"}
-
-
-tmp = MyType.new
-tmp["foo"] = "bar"
-tmp
-
-
-tmp = MyType(typeof("foo"), typeof("bar")).new
-tmp["foo"] = "bar"
-tmp
-
-
-MyType(String, String) {"foo": "bar"}
-
-
-:hello
-:good_bye
-
-# With spaces and symbols
-:"symbol with spaces"
-
-# Ending with question and exclamation marks
-:question?
-:exclamation!
-
-# For the operators
-:+
-:-
-:*
-:/
-:==
-:<
-:<=
-:>
-:>=
-:!
-:!=
-:=~
-:!~
-:&
-:|
-:^
-:~
-:**
-:>>
-:<<
-:%
-:[]
-:[]?
-:[]=
-:<=>
-:===
-
-
-x..y # an inclusive range, in mathematics: [x, y]
-x...y # an exclusive range, in mathematics: [x, y)
-
-
-# A proc without arguments
-->{ 1 } # Proc(Int32)
-
-# A proc with one argument
-->(x : Int32) { x.to_s } # Proc(Int32, String)
-
-# A proc with two arguments:
-->(x : Int32, y : Int32) { x + y } # Proc(Int32, Int32, Int32)
-
-
-Proc(Int32, String).new { |x| x.to_s } # Proc(Int32, String)
-
-
-proc = ->(x : Int32, y : Int32) { x + y }
-proc.call(1, 2) #=> 3
-
-
-def one
- 1
-end
-
-proc = ->one
-proc.call #=> 1
-
-
-def plus_one(x)
- x + 1
-end
-
-proc = ->plus_one(Int32)
-proc.call(41) #=> 42
-
-
-str = "hello"
-proc = ->str.count(Char)
-proc.call('e') #=> 1
-proc.call('l') #=> 2
-
-
-tuple = {1, "hello", 'x'} # Tuple(Int32, String, Char)
-tuple[0] #=> 1 (Int32)
-tuple[1] #=> "hello" (String)
-tuple[2] #=> 'x' (Char)
-
-
-[1, 2, 3] # Array(Int32)
-[1, "hello", 'x'] # Array(Int32 | String | Char)
-
-
-[] of Int32 # same as Array(Int32).new
-
-
-%w(one two three) # ["one", "two", "three"]
-
-
-%i(one two three) # [:one, :two, :three]
-
-
-MyType{1, 2, 3}
-
-
-tmp = MyType.new
-tmp << 1
-tmp << 2
-tmp << 3
-tmp
-
-
-tmp = MyType(typeof(1, 2, 3)).new
-tmp << 1
-tmp << 2
-tmp << 3
-tmp
-
-
-MyType(Int32 | String) {1, 2, "foo"}
-
-
-nil
-
-
-1 # Int32
-
-1_i8 # Int8
-1_i16 # Int16
-1_i32 # Int32
-1_i64 # Int64
-
-1_u8 # UInt8
-1_u16 # UInt16
-1_u32 # UInt32
-1_u64 # UInt64
-
-+10 # Int32
--20 # Int32
-
-2147483648 # Int64
-9223372036854775808 # UInt64
-
-
-1_000_000 # better than 1000000
-
-
-0b1101 # == 13
-
-
-0o123 # == 83
-
-
-0xFE012D # == 16646445
-0xfe012d # == 16646445
-
-
-true # A Bool that is true
-false # A Bool that is false
-
-
-a = 1
-
-ptr = pointerof(a)
-ptr.value = 2
-
-a #=> 2
-
-
-class Point
- def initialize(@x, @y)
- end
-
- def x
- @x
- end
-
- def x_ptr
- pointerof(@x)
- end
-end
-
-point = Point.new 1, 2
-
-ptr = point.x_ptr
-ptr.value = 10
-
-point.x #=> 10
-
-
-def add(x : Number, y : Number)
- x + y
-end
-
-# Ok
-add 1, 2 # Ok
-
-# Error: no overload matches 'add' with types Bool, Bool
-add true, false
-
-
-def add(x, y)
- x + y
-end
-
-add true, false
-
-
-# A class that has a + method but isn't a Number
-class Six
- def +(other)
- 6 + other
- end
-end
-
-# add method without type restrictions
-def add(x, y)
- x + y
-end
-
-# OK
-add Six.new, 10
-
-# add method with type restrictions
-def restricted_add(x : Number, y : Number)
- x + y
-end
-
-# Error: no overload matches 'restricted_add' with types Six, Int32
-restricted_add Six.new, 10
-
-
-class Person
- def ==(other : self)
- other.name == name
- end
-
- def ==(other)
- false
- end
-end
-
-john = Person.new "John"
-another_john = Person.new "John"
-peter = Person.new "Peter"
-
-john == another_john #=> true
-john == peter #=> false (names differ)
-john == 1 #=> false (because 1 is not a Person)
-
-
-class Person
- def self.compare(p1 : self, p2 : self)
- p1.name == p2.name
- end
-end
-
-john = Person.new "John"
-peter = Person.new "Peter"
-
-Person.compare(john, peter) # OK
-
-
-def foo(x : Int32)
-end
-
-foo 1 # OK
-foo "hello" # Error
-
-
-def foo(x : Int32.class)
-end
-
-foo Int32 # OK
-foo String # Error
-
-
-def foo(x : Int32.class)
- puts "Got Int32"
-end
-
-def foo(x : String.class)
- puts "Got String"
-end
-
-foo Int32 # prints "Got Int32"
-foo String # prints "Got String"
-
-
-def foo(*args : Int32)
-end
-
-def foo(*args : String)
-end
-
-foo 1, 2, 3 # OK, invokes first overload
-foo "a", "b", "c" # OK, invokes second overload
-foo 1, 2, "hello" # Error
-foo() # Error
-
-
-def foo
- # This is the empty-tuple case
-end
-
-
-def foo(x : T)
- T
-end
-
-foo(1) #=> Int32
-foo("hello") #=> String
-
-
-def foo(x : Array(T))
- T
-end
-
-foo([1, 2]) #=> Int32
-foo([1, "a"]) #=> (Int32 | String)
-
-
-def foo(x : T.class)
- Array(T)
-end
-
-foo(Int32) #=> Array(Int32)
-foo(String) #=> Array(String)
-
-
-class Person
- # Increases age by one
- def become_older
- @age += 1
- end
-
- # Increases age by the given number of years
- def become_older(years : Int32)
- @age += years
- end
-
- # Increases age by the given number of years, as a String
- def become_older(years : String)
- @age += years.to_i
- end
-
- # Yields the current age of this person and increases
- # its age by the value returned by the block
- def become_older
- @age += yield @age
- end
-end
-
-person = Person.new "John"
-
-person.become_older
-person.age #=> 1
-
-person.become_older 5
-person.age #=> 6
-
-person.become_older "12"
-person.age #=> 18
-
-person.become_older do |current_age|
- current_age < 20 ? 10 : 30
-end
-person.age #=> 28
-
-
-a = 1
-a.is_a?(Int32) #=> true
-a.is_a?(String) #=> false
-a.is_a?(Number) #=> true
-a.is_a?(Int32 | String) #=> true
-
-
-# One for each thread
-@[ThreadLocal]
-$values = [] of Int32
-
-
-@[AlwaysInline]
-def foo
- 1
-end
-
-
-@[NoInline]
-def foo
- 1
-end
-
-
-lib LibFoo
- @[CallConvention("X86_StdCall")]
- fun foo : Int32
-end
-
-
-def sum(*elements)
- total = 0
- elements.each do |value|
- total += value
- end
- total
-end
-
-# elements is Tuple(Int32, Int32, Int32, Float64)
-sum 1, 2, 3, 4.5
-
-
-if a.responds_to?(:abs)
- # here a's type will be reduced to those responding to the 'abs' method
-end
-
-
-a = some_condition ? 1 : "hello"
-# a : Int32 | String
-
-if a.responds_to?(:abs)
- # here a will be Int32, since Int32#abs exists but String#abs doesn't
-else
- # here a will be String
-end
-
-
-if (a = @a).responds_to?(:abs)
- # here a is guaranteed to respond to `abs`
-end
-
-
-def capture(&block)
- block
-end
-
-def invoke(&block)
- block.call
-end
-
-proc = capture { puts "Hello" }
-invoke(&proc) # prints "Hello"
-
-
-
-
-def capture(&block)
- block
-end
-
-def twice
- yield
- yield
-end
-
-proc = capture { puts "Hello" }
-twice &proc
-
-
-twice &->{ puts "Hello" }
-
-
-def say_hello
- puts "Hello"
-end
-
-twice &->say_hello
-
-
-def foo
- yield 1
-end
-
-def wrap_foo
- puts "Before foo"
- foo do |x|
- yield x
- end
- puts "After foo"
-end
-
-wrap_foo do |i|
- puts i
-end
-
-
-def foo
- yield 1
-end
-
-def wrap_foo(&block : Int32 -> _)
- puts "Before foo"
- foo(&block)
- puts "After foo"
-end
-
-wrap_foo do |i|
- puts i
-end
-
-
-foo_forward do |i|
- break # error
-end
-
-
-a = 2
-while (a += 1) < 20
- if a == 10
- # goes to 'puts a'
- break
- end
-end
-puts a #=> 10
-
-
-class Person
- private def say(message)
- puts message
- end
-
- def say_hello
- say "hello" # OK, no receiver
- self.say "hello" # Error, self is a receiver
-
- other = Person.new "Other"
- other.say "hello" # Error, other is a receiver
- end
-end
-
-
-class Employee < Person
- def say_bye
- say "bye" # OK
- end
-end
-
-
-module Namespace
- class Foo
- protected def foo
- puts "Hello"
- end
- end
-
- class Bar
- def bar
- # Works, because Foo and Bar are under Namespace
- Foo.new.foo
- end
- end
-end
-
-Namespace::Bar.new.bar
-
-
-class Person
- protected def self.say(message)
- puts message
- end
-
- def say_hello
- Person.say "hello"
- end
-end
-
-
-buffer = uninitialized UInt8[256]