├── .gitignore ├── LICENSE ├── README.md ├── abstract └── abstract.cr ├── array └── array.cr ├── buffered-channel └── buffered-channel.cr ├── case └── case.cr ├── channel-select └── channel-select.cr ├── channel-synchronization └── channel-synchronization.cr ├── channel └── channel.cr ├── closing-channels ├── closing-channels-exception.cr ├── closing-channels-nil.cr └── closing-channels-nonatomic.cr ├── closures └── closures.cr ├── command-line-args └── argv.cr ├── complex └── complex.cr ├── constants └── constants.cr ├── container └── container.cr ├── def └── def.cr ├── enumerable-functions └── enumerable-functions.cr ├── epoch └── epoch.cr ├── file-read-write └── file-read-write.cr ├── free └── free.cr ├── hash └── hash.cr ├── hello └── hello.cr ├── if-else └── if-else.cr ├── json └── json.cr ├── named_tuple └── named_tuple.cr ├── pointer_like_helper_structure └── pointer_like_helper_structure.cr ├── random └── random.cr ├── range └── range.cr ├── reading-files └── reading-files.cr ├── recursion └── recursion.cr ├── regular-expressions └── regular-expressions.cr ├── run_all.cr ├── spawn └── spawn.cr ├── string_object └── string_object.cr ├── strings └── strings.cr ├── struct └── struct.cr ├── subclasses └── subclasses_discovery_macro.cr ├── tickers └── tickers.cr ├── time-formatting-parsing └── time-formatting-parsing.cr ├── time └── time.cr ├── tuple └── tuple.cr ├── type_restriction └── type_restriction.cr ├── url-parsing └── url-parsing.cr ├── values └── values.cr ├── variables └── variables.cr ├── while └── while.cr └── worker-pools └── worker-pools.cr /.gitignore: -------------------------------------------------------------------------------- 1 | **/doc/ 2 | **/libs/ 3 | **/.crystal/ 4 | **/.shards/ 5 | 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Aşkın Gedik 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Crystal Programming Language Examples 2 | 3 | * [Hello](hello/hello.cr) 4 | * [Values](values/values.cr) 5 | * [Variables](variables/variables.cr) 6 | * [While](while/while.cr) 7 | * [If-else](if-else/if-else.cr) 8 | * [Case](case/case.cr) 9 | * [Command Line Arguments](command-line-args/argv.cr) 10 | * [Array](array/array.cr) 11 | * [Tuple](tuple/tuple.cr) 12 | * [Hash](hash/hash.cr) 13 | * [Range](range/range.cr) 14 | * [Def](def/def.cr) 15 | * [Closures](closures/closures.cr) 16 | * [Recursion](recursion/recursion.cr) 17 | * [Struct](struct/struct.cr) 18 | * [Abstract](abstract/abstract.cr) 19 | * [Spawn](spawn/spawn.cr) 20 | * [Channel](channel/channel.cr) 21 | * [Buffered channel](buffered-channel/buffered-channel.cr) 22 | * [Channel synchronization](channel-synchronization/channel-synchronization.cr) 23 | * [Channel select](channel-select/channel-select.cr) 24 | * Closing channels 25 | * [Closing channels with control channel](closing-channels/closing-channels-nonatomic.cr) 26 | * [Closing channels using receive?](closing-channels/closing-channels-nil.cr) 27 | * [Closing channels using exception](closing-channels/closing-channels-exception.cr) 28 | * [Tickers](tickers/tickers.cr) 29 | * [Worker pools](worker-pools/worker-pools.cr) 30 | * [Enumerable functions](enumerable-functions/enumerable-functions.cr) 31 | * [Strings](strings/strings.cr) 32 | * [Regular expressions](regular-expressions/regular-expressions.cr) 33 | * [Json](json/json.cr) 34 | * [Time](time/time.cr) 35 | * [Epoch](epoch/epoch.cr) 36 | * [Time formatting parsing](time-formatting-parsing/time-formatting-parsing.cr) 37 | * [Random](random/random.cr) 38 | * [Url parsing](url-parsing/url-parsing.cr) 39 | * [Reading-files](reading-files/reading-files.cr) 40 | -------------------------------------------------------------------------------- /abstract/abstract.cr: -------------------------------------------------------------------------------- 1 | # class Foo 2 | # abstract def foo 3 | # end 4 | # Error in abstract/abstract.cr:2: can't define abstract def on non-abstract class 5 | 6 | abstract class Foo 7 | abstract def foo 8 | end 9 | 10 | class Bar < Foo 11 | def foo 12 | 1 13 | end 14 | end 15 | 16 | # --- 17 | 18 | abstract class Foo 19 | abstract def foo 20 | end 21 | 22 | # --- 23 | 24 | abstract class Geometry(T) 25 | abstract def area : T 26 | abstract def perim : T 27 | end 28 | 29 | class Rect < Geometry(Int32) 30 | def initialize(@width : T, @height : T) 31 | end 32 | 33 | def area 34 | @width * @height 35 | end 36 | 37 | def perim 38 | 2 * @width + 2 * @height 39 | end 40 | end 41 | 42 | puts Rect.new(3, 6).area 43 | -------------------------------------------------------------------------------- /array/array.cr: -------------------------------------------------------------------------------- 1 | a = [] of Int32 2 | puts a 3 | 4 | # 6 elemanlı 0 ile dolu bir array 5 | b = Array(Int32).new(6, 0) 6 | b[3] = 100 7 | puts b # [0, 0, 0, 100, 0, 0] 8 | 9 | puts "Len: #{b.size}" # 6 10 | 11 | c = [1, 2, 3, 4, 5] of Int32 12 | puts c 13 | 14 | two_d = [[0, 0], [0, 0]] 15 | puts two_d #  [[0, 0], [0, 0]] 16 | 17 | two_e = Array(Array(Int32)).new(2, [0, 0]) 18 | puts two_e #  [[0, 0], [0, 0]] 19 | -------------------------------------------------------------------------------- /buffered-channel/buffered-channel.cr: -------------------------------------------------------------------------------- 1 | ch = Channel(Int32).new(3) 2 | ch.send 7 3 | ch.send 5 4 | 5 | 2.times { 6 | puts "Yo" 7 | puts ch.receive 8 | } 9 | -------------------------------------------------------------------------------- /case/case.cr: -------------------------------------------------------------------------------- 1 | x = 1 2 | case x 3 | when 1 4 | 'b' 5 | when 2 6 | 'c' 7 | else 8 | 'd' 9 | end 10 | 11 | __temp_1 = x 12 | if 1 === __temp_1 13 | 'b' 14 | elsif 2 === __temp_1 15 | 'c' 16 | else 17 | 'd' 18 | end 19 | 20 | # --- 21 | x = 1 22 | case x 23 | when 1, 2 24 | 'b' 25 | end 26 | 27 | if 1 === x || 2 === x 28 | 'b' 29 | end 30 | 31 | #  --- 32 | case x = 1 33 | when 2 34 | 3 35 | end 36 | 37 | x = 1 38 | if 2 === x 39 | 3 40 | end 41 | 42 | # --- 43 | case 44 | when 2, 9 45 | 3 46 | when 4 47 | 5 48 | end 49 | 50 | if 2 || 9 51 | 3 52 | elsif 4 53 | 5 54 | end 55 | 56 | # --- 57 | x = 1 58 | case x 59 | when nil 60 | 'b' 61 | end 62 | if x.is_a?(::Nil) 63 | 'b' 64 | end 65 | 66 | #  --- 67 | s = "askn" 68 | case s 69 | when .size 70 | 2 71 | end 72 | __temp_1 = s 73 | if __temp_1.size 74 | 2 75 | end 76 | -------------------------------------------------------------------------------- /channel-select/channel-select.cr: -------------------------------------------------------------------------------- 1 | def generator(n : T) forall T 2 | channel = Channel(T).new 3 | spawn do 4 | loop do 5 | sleep n 6 | channel.send n 7 | end 8 | end 9 | channel 10 | end 11 | 12 | ch1 = generator(1) 13 | ch2 = generator(1.5) 14 | ch3 = generator(5) 15 | 16 | loop do 17 | index, value = Channel.select( 18 | ch1.receive_select_action, 19 | ch2.receive_select_action, 20 | ch3.receive_select_action 21 | ) 22 | 23 | case index 24 | when 0 25 | int = value.as(typeof(ch1.receive)) 26 | puts "Int: #{value}" 27 | when 1 28 | float = value.as(typeof(ch2.receive)) 29 | puts "Float: #{value}" 30 | when 2 31 | break 32 | else 33 | raise "BUG: Channel.select returned invalid index #{index}" 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /channel-synchronization/channel-synchronization.cr: -------------------------------------------------------------------------------- 1 | def worker(count : Int32, done : Channel(Bool)) 2 | puts "working #{count}" 3 | sleep count 4 | puts "done #{count}" 5 | done.send true 6 | end 7 | 8 | done = Channel(Bool).new 9 | worker_count = 10 10 | worker_count.times do |count| 11 | spawn worker(count, done) 12 | end 13 | # eğer bu satırı silersek başlamasını beklemeden çıkar 14 | worker_count.times do 15 | done.receive 16 | end 17 | -------------------------------------------------------------------------------- /channel/channel.cr: -------------------------------------------------------------------------------- 1 | c = Channel(String).new 2 | spawn do 3 | c.send "ping" 4 | end 5 | 6 | puts Channel.receive_first(c) 7 | 8 | ch = Channel(Int32).new 9 | spawn { sleep 3; ch.send 1 } 10 | spawn { sleep 1; ch.send 2 } 11 | spawn { sleep 2; ch.send 3 } 12 | 13 | puts (1..3).map { ch.receive } 14 | -------------------------------------------------------------------------------- /closing-channels/closing-channels-exception.cr: -------------------------------------------------------------------------------- 1 | jobs = Channel(Int32).new(5) 2 | 3 | def foo(jobs) 4 | loop do 5 | begin 6 | item = jobs.receive 7 | puts "received job #{item}" 8 | rescue 9 | puts "received all jobs" 10 | return 11 | end 12 | end 13 | end 14 | 15 | spawn { 16 | 3.times do |j| 17 | jobs.send j 18 | puts "sent job #{j}" 19 | end 20 | puts("sent all jobs") 21 | jobs.close 22 | } 23 | 24 | foo(jobs) 25 | -------------------------------------------------------------------------------- /closing-channels/closing-channels-nil.cr: -------------------------------------------------------------------------------- 1 | jobs = Channel(Int32).new(5) 2 | 3 | def foo(jobs) 4 | while item = jobs.receive? 5 | puts "received job #{item}" 6 | end 7 | puts "received all jobs" 8 | end 9 | 10 | spawn { 11 | 3.times do |j| 12 | jobs.send j 13 | puts "sent job #{j}" 14 | end 15 | puts("sent all jobs") 16 | jobs.close 17 | } 18 | 19 | foo(jobs) 20 | -------------------------------------------------------------------------------- /closing-channels/closing-channels-nonatomic.cr: -------------------------------------------------------------------------------- 1 | jobs = Channel(Int32).new(5) 2 | done = Channel(Bool).new 3 | 4 | def foo(done, jobs) 5 | loop do 6 | if jobs.closed? && !jobs.empty? 7 | puts "received job #{jobs.receive}" 8 | else 9 | puts "received all jobs" 10 | done.send true 11 | return 12 | end 13 | end 14 | end 15 | 16 | spawn foo(done, jobs) 17 | 18 | 3.times do |j| 19 | jobs.send j 20 | puts "sent job #{j}" 21 | end 22 | 23 | jobs.close 24 | puts("sent all jobs") 25 | done.receive 26 | -------------------------------------------------------------------------------- /closures/closures.cr: -------------------------------------------------------------------------------- 1 | x = 0 2 | proc = ->{ x += 1; x } 3 | puts proc.call # => 1 4 | puts proc.call # => 2 5 | 6 | 7 | def counter 8 | x = 0 9 | ->{ x += 1; x } 10 | end 11 | 12 | proc = counter 13 | puts proc.call # => 1 14 | puts proc.call # => 2 15 | -------------------------------------------------------------------------------- /command-line-args/argv.cr: -------------------------------------------------------------------------------- 1 | # Demo of command line arguments 2 | # ARGV[0]: First command line argument 3 | # (not the executable name) 4 | # (Be aware: `crystal build` sends all arguments to the compiler. 5 | # Add an additional `--` between compiler arguments and the other) 6 | # ARGV is an array of strings 7 | puts "Number of command line arguments: #{ARGV.size}" 8 | ARGV.each_with_index {|arg, i| puts "Argument #{i}: #{arg}"} 9 | 10 | # The executable name is available as PROGRAM_NAME 11 | puts "Executable name: #{PROGRAM_NAME}" 12 | -------------------------------------------------------------------------------- /complex/complex.cr: -------------------------------------------------------------------------------- 1 | require "colorize" 2 | require "complex" 3 | x1 = Complex.new(1, 0) 4 | x2 = Complex.new(2, 1) 5 | pp x1 6 | pp x2 7 | puts 8 | p "x1 + x2 = #{x1 + x2}" 9 | p "x1 - x2 = #{x1 - x2}" 10 | p "x1 * x2 = #{x1 * x2}" 11 | p "x1 / x2 = #{x1 / x2}" 12 | -------------------------------------------------------------------------------- /constants/constants.cr: -------------------------------------------------------------------------------- 1 | PI = 3.14 2 | 3 | module Earth 4 | RADIUS = 6_371_000 5 | end 6 | 7 | puts PI 8 | puts Earth::RADIUS 9 | -------------------------------------------------------------------------------- /container/container.cr: -------------------------------------------------------------------------------- 1 | class Container(T) 2 | 3 | def initialize(@values : T) 4 | pp @values 5 | pp typeof(@values) 6 | end 7 | end 8 | 9 | Container.new([1,2,3]) 10 | Container.new([1.0, 3.0, 4.0]) 11 | value = [[1, 2], [4,3,2],[1]] 12 | Container.new(value) 13 | value = [[1.0, 4.5], [2.2, 0.0]] 14 | Container.new(value) 15 | -------------------------------------------------------------------------------- /def/def.cr: -------------------------------------------------------------------------------- 1 | def String.askin 2 | "askin" 3 | end 4 | 5 | puts String.askin 6 | 7 | class String 8 | def tsk 9 | "tisikkirlir " + self 10 | end 11 | end 12 | 13 | puts "ali".tsk 14 | 15 | def foo(x : Int, y : Float) 16 | end 17 | 18 | def foo(x, y : Int32 = 1, z : Int64 = 2) 19 | x + y + z 20 | end 21 | 22 | def foo(x : T) forall T 23 | end 24 | 25 | foo(3) # x = 3, T = Int32 26 | 27 | #  return type 28 | 29 | 30 | def sa(name : String) : Int32 31 | 3 32 | end 33 | 34 | puts sa("ali") 35 | 36 | # --- 37 | def a : {Int32, String} 38 | return 1, "2" 39 | end 40 | 41 | puts a 42 | -------------------------------------------------------------------------------- /enumerable-functions/enumerable-functions.cr: -------------------------------------------------------------------------------- 1 | strs = {"peach", "apple", "pear", "plum"} 2 | 3 | puts strs.index("pear") 4 | puts strs.includes?("grape") 5 | puts strs.any? { |v| v.starts_with? "p" } 6 | puts strs.all? { |v| v.starts_with? "p" } 7 | puts strs.select { |v| v.includes? "e" } 8 | puts strs.map { |v| v.upcase } 9 | -------------------------------------------------------------------------------- /epoch/epoch.cr: -------------------------------------------------------------------------------- 1 | puts Time.unix(628232400) 2 | t = Time.new(1989, 11, 28, 5, 0, 0) 3 | puts t.to_unix 4 | puts t.to_unix_ms 5 | #  1989-11-28 05:00:00 UTC 6 | -------------------------------------------------------------------------------- /file-read-write/file-read-write.cr: -------------------------------------------------------------------------------- 1 | # This is not an in-depth guide to file operations but 2 | # merely a basic idea how to work with text files in crystal 3 | 4 | # use this path for our file 5 | path = "example.txt" 6 | # create a new file and open it in write mode 7 | # other files with the same name will be overwritten 8 | example_file = File.new path, "w" 9 | example_file.puts "This fancy string will be written inside the file" 10 | # now close the file 11 | example_file.close 12 | 13 | # check if it exists before opening 14 | abort "file is missing", 1 if !File.file? path 15 | # and read its content to a string 16 | content = File.read path 17 | puts content # => This fancy string will b... 18 | 19 | # or just open it for further operations 20 | our_file = File.open path, "w" 21 | our_file.puts "Another line" 22 | our_file.close 23 | 24 | # we can also use iterators to work with files directly 25 | File.each_line path do |line| 26 | puts line # => Another line 27 | end 28 | # Note that .puts will overwrite previous file contents 29 | 30 | # Read bytes 31 | File.open("example.txt") do |io| # This block autoclose file 32 | buffer = Bytes.new(io.size) # Create buffer with io size 33 | io.read(buffer) # Fill buffer with IO 34 | pp buffer 35 | end 36 | 37 | -------------------------------------------------------------------------------- /free/free.cr: -------------------------------------------------------------------------------- 1 | class Foo 2 | def initialize 3 | @x = 10 4 | @y = "some string" 5 | puts "initialized" 6 | end 7 | 8 | def finalize 9 | puts "Never called" 10 | end 11 | end 12 | 13 | foo = Foo.new 14 | p foo # => # 15 | GC.free(Pointer(Void).new(foo.object_id)) # This line frees the memory 16 | #p foo # => # 17 | p foo.class 18 | p foo = nil 19 | p foo.class 20 | -------------------------------------------------------------------------------- /hash/hash.cr: -------------------------------------------------------------------------------- 1 | a = {} of String => Int32 2 | a["gs"] = 1905 3 | 4 | puts a 5 | 6 | b = Hash(Int32 | Char, Int32){3 => 4} 7 | b[1] = 2 8 | b['a'] = 9 9 | puts b 10 | 11 | puts b.size 12 | 13 | b.delete('a') 14 | puts b 15 | 16 | p b["bar"]? # nil 17 | -------------------------------------------------------------------------------- /hello/hello.cr: -------------------------------------------------------------------------------- 1 | puts "hello world" 2 | -------------------------------------------------------------------------------- /if-else/if-else.cr: -------------------------------------------------------------------------------- 1 | if 7 % 2 == 0 2 | puts "7 is even" 3 | else 4 | puts "7 is odd" 5 | end 6 | 7 | if 8 % 4 == 0 8 | puts "8 is divisible by 4" 9 | end 10 | 11 | if (num = 9) < 0 12 | puts "#{num}, is negative" 13 | elsif num < 10 14 | puts "#{num}, has 1 digit" 15 | else 16 | puts "#{num}, has multiple digits" 17 | end 18 | -------------------------------------------------------------------------------- /json/json.cr: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | puts true.to_json 4 | puts "askn".to_json 5 | puts 1.to_json 6 | puts 12.14.to_json 7 | puts ["apple", "peach", "pear"].to_json 8 | puts Hash{"apple" => 5, "lettuce" => 7}.to_json 9 | 10 | # json_object 11 | # json_array 12 | # field 13 | result = JSON.build do |json| 14 | json.object do 15 | json.field "address", "Crystal Road 1234" 16 | json.field "location" do 17 | json.array do 18 | json.number 12.3 19 | json.number 34.5 20 | end 21 | end 22 | end 23 | end 24 | puts result # => %({"address":"Crystal Road 1234","location":[12.3,34.5]}) 25 | 26 | # --- 27 | 28 | json = %({"page": 1, "fruits": ["apple", "peach"]}) 29 | puts JSON.parse json 30 | 31 | class Location 32 | JSON.mapping({ 33 | lat: Float64, 34 | lng: Float64, 35 | }) 36 | end 37 | 38 | # emit_null: default null 39 | #  nilable: nil olabilir 40 | # 41 | class House 42 | JSON.mapping({ 43 | address: String, 44 | location: {type: Location, nilable: true}, 45 | time: {type: Time, converter: Time::Format.new("%F"), emit_null: true, key: "value"}, 46 | }) 47 | end 48 | 49 | house = House.from_json(%({"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}, "value": "2014-10-31 23:37:16"})) 50 | p house 51 | # , @time=2014-10-31 00:00:00> 52 | -------------------------------------------------------------------------------- /named_tuple/named_tuple.cr: -------------------------------------------------------------------------------- 1 | strings = {string_1: "String 1", 2 | string_2: "String 2", 3 | string_3: "String 3"} 4 | 5 | puts strings[:string_1] 6 | puts strings[:string_2] 7 | puts strings[:string_3] 8 | -------------------------------------------------------------------------------- /pointer_like_helper_structure/pointer_like_helper_structure.cr: -------------------------------------------------------------------------------- 1 | # License is MIT, though I always appreciate a short in-source comment like I prepared. 2 | # But as it's MIT, you may omit it of course. 3 | 4 | # Helper structure which acts like a pointer, but allows direct access to the 5 | # underlying object by delegating almost all calls on it to the pointee. 6 | # 7 | # It's best compared to C's -> operator. 8 | # 9 | # (Based on https://gist.github.com/Papierkorb/c46e205e27e4c341965438b18e28e09e) 10 | struct Ref(T) 11 | getter ptr : Pointer(T) 12 | 13 | def self.create 14 | new(T.new) 15 | end 16 | 17 | def initialize(@ptr : Pointer(T)) 18 | end 19 | 20 | def initialize(obj : Reference) 21 | @ptr = pointerof(obj) 22 | end 23 | 24 | def initialize(val : Value) 25 | @ptr = Pointer(T).malloc 26 | @ptr.value = val 27 | end 28 | 29 | macro method_missing(call) 30 | @ptr.value.{{ call }} 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /random/random.cr: -------------------------------------------------------------------------------- 1 | puts rand(100) # 0 <= x < 100 2 | puts rand # 0 <= x < 1 3 | 4 | r = Random.new(42) 5 | puts r.rand 6 | puts r.rand 7 | 8 | y = Random.new(42) 9 | puts y.rand 10 | puts y.rand 11 | -------------------------------------------------------------------------------- /range/range.cr: -------------------------------------------------------------------------------- 1 | 'a'..'z' 2 | 0...10 3 | Range.new(1, 10) 4 | -------------------------------------------------------------------------------- /reading-files/reading-files.cr: -------------------------------------------------------------------------------- 1 | puts File.read("./reading-files.cr") 2 | 3 | f = File.read_lines("./reading-files.cr") 4 | -------------------------------------------------------------------------------- /recursion/recursion.cr: -------------------------------------------------------------------------------- 1 | def fact(n : Int) : Int 2 | if n == 0 3 | return 1 4 | end 5 | return n * fact(n - 1) 6 | end 7 | 8 | puts fact 7 9 | -------------------------------------------------------------------------------- /regular-expressions/regular-expressions.cr: -------------------------------------------------------------------------------- 1 | puts "peach".match /p([a-z]+)ch/ 2 | puts /p([a-z]+)ch/.match "peach" 3 | 4 | puts /p([a-z]+)ch/ =~ "peach" 5 | 6 | puts "peach".scan /p([a-z]+)ch/ 7 | -------------------------------------------------------------------------------- /run_all.cr: -------------------------------------------------------------------------------- 1 | require "colorize" 2 | files = Dir["./**/**.cr"] 3 | 4 | files.each do |x| 5 | next if x == "./run_all.cr" 6 | print "--------" 7 | x.size.times { print "-" } 8 | puts 9 | puts "Running #{x}".colorize(:blue) 10 | op = system("cd #{File.dirname(x)} && crystal #{File.basename(x)}") 11 | unless op 12 | puts "Error detected - exiting!".colorize(:red) 13 | exit 1 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spawn/spawn.cr: -------------------------------------------------------------------------------- 1 | def xxx(name) 2 | sleep 4 3 | 3.times do |i| 4 | puts "#{name} - #{i}" 5 | end 6 | end 7 | 8 | xxx("normal") 9 | 10 | spawn xxx("spawn") 11 | 12 | spawn do 13 | sleep 3 14 | puts "Finished from 3" 15 | end 16 | 17 | spawn do 18 | sleep 5 19 | puts "Finished from 5" 20 | end 21 | 22 | sleep 6 23 | -------------------------------------------------------------------------------- /string_object/string_object.cr: -------------------------------------------------------------------------------- 1 | struct StringObj 2 | getter string_1 3 | getter string_2 4 | getter string_3 5 | getter string_4 6 | getter string_5 7 | getter string_6 8 | getter string_7 9 | getter string_8 10 | getter string_9 11 | getter string_10 12 | 13 | def initialize 14 | @string_1 = "str.string_1" 15 | @string_2 = "str.string_2" 16 | @string_3 = "str.string_3" 17 | @string_4 = "str.string_4" 18 | @string_5 = "str.string_5" 19 | @string_6 = "str.string_6" 20 | @string_7 = "str.string_7" 21 | @string_8 = "str.string_8" 22 | @string_9 = "str.string_9" 23 | @string_10 = "str.string_10" 24 | end 25 | end 26 | 27 | str = StringObj.new 28 | p str.string_1 29 | p str.string_2 30 | p str.string_3 31 | p str.string_4 32 | p str.string_5 33 | p str.string_6 34 | p str.string_7 35 | p str.string_8 36 | p str.string_9 37 | p str.string_10 38 | -------------------------------------------------------------------------------- /strings/strings.cr: -------------------------------------------------------------------------------- 1 | puts "includes?: #{"test".includes? "es"}" 2 | puts "count: #{"test".count "t"}" 3 | puts "starts with?: #{"test".starts_with? "te"}" 4 | puts "ends with?: #{"test".ends_with?("st")}" 5 | puts "index: #{"test".index("e")}" 6 | puts "join: #{{"a", "b"}.join("-")}" 7 | puts "gsub: #{"foo".gsub("o", "0")}" 8 | puts "sub: #{"foo".sub("o", "0")}" 9 | puts "split: #{"a-b-c-d-e".split("-")}" 10 | puts "downcase: #{"TEST".downcase}" 11 | puts "upcase: #{"test".upcase}" 12 | puts 13 | puts "size: #{"hello".size}" 14 | puts "char: #{"hello"[1]}" 15 | -------------------------------------------------------------------------------- /struct/struct.cr: -------------------------------------------------------------------------------- 1 | struct Foo(T) 2 | end 3 | 4 | Foo(Int32) 5 | 6 | # --- 7 | struct Foo 8 | end 9 | 10 | # struct Bar < Foo 11 | # end 12 | # Error in ./struct/struct.cr:10: can't extend non-abstract struct Foo 13 | 14 | abstract struct AbstractFoo 15 | end 16 | 17 | struct Bar < AbstractFoo 18 | end 19 | 20 | # --- 21 | struct Test 22 | def initialize(@test : String) 23 | end 24 | end 25 | 26 | Test.new("foo") 27 | 28 | # --- 29 | struct User 30 | property name, age 31 | 32 | def initialize(@name : String, @age : Int32) 33 | end 34 | 35 | def print 36 | puts "#{age} - #{name}" 37 | end 38 | end 39 | 40 | puts User.new("osman", 3).name 41 | User.new("ali", 9).print 42 | -------------------------------------------------------------------------------- /subclasses/subclasses_discovery_macro.cr: -------------------------------------------------------------------------------- 1 | class Base 2 | SUBCLASSES = {% begin %} 3 | [ 4 | {% for clazz in Base.subclasses %} 5 | {{clazz.methods.map(&.name.stringify)}} of String, 6 | {% end %} 7 | ] of Array(String) 8 | {% end %} 9 | end 10 | 11 | class Foo < Base 12 | def foo 13 | end 14 | 15 | def bar 16 | end 17 | end 18 | 19 | class Bar < Base 20 | def baz 21 | end 22 | end 23 | 24 | puts Base::SUBCLASSES -------------------------------------------------------------------------------- /tickers/tickers.cr: -------------------------------------------------------------------------------- 1 | class Ticker 2 | def initialize(@duration : Float64) 3 | @c = Channel(Nil).new 4 | end 5 | 6 | def start_timer 7 | spawn do 8 | loop do 9 | sleep @duration 10 | @c.send nil 11 | end 12 | end 13 | end 14 | 15 | def stop_timer 16 | @c.close 17 | end 18 | 19 | def each(&block) 20 | start_timer 21 | spawn do 22 | until @c.closed? 23 | block.call 24 | @c.receive 25 | end 26 | end 27 | end 28 | end 29 | 30 | ticker = Ticker.new(0.5) 31 | ticker.each do 32 | puts Time.local 33 | end 34 | 35 | sleep 3 36 | -------------------------------------------------------------------------------- /time-formatting-parsing/time-formatting-parsing.cr: -------------------------------------------------------------------------------- 1 | puts Time.parse_utc("2012-11-01 22:08:12", "%F %T") 2 | 3 | puts Time.parse_utc("Fri Oct 31 23:00:24 2014", "%c") 4 | 5 | puts Time.parse_utc("20150624", "%Y%m%d") 6 | -------------------------------------------------------------------------------- /time/time.cr: -------------------------------------------------------------------------------- 1 | # using local time 2 | puts Time.local 3 | t = Time.local(2002, 10, 31, 2, 2, 2) 4 | p t 5 | puts t.year 6 | puts t.month 7 | puts t.day 8 | puts t.hour 9 | puts t.minute 10 | puts t.second 11 | puts t.day_of_week 12 | 13 | # using UTC time 14 | puts Time.utc 15 | t = Time.utc(2002, 10, 31, 2, 2, 2) 16 | p t 17 | puts t.year 18 | puts t.month 19 | puts t.day 20 | puts t.hour 21 | puts t.minute 22 | puts t.second 23 | puts t.day_of_week 24 | -------------------------------------------------------------------------------- /tuple/tuple.cr: -------------------------------------------------------------------------------- 1 | tuple = {1, 2.5, 'a'} 2 | puts tuple[0] 3 | 4 | a = Tuple.new(1, "hello", 'x') 5 | puts a 6 | 7 | b = a.clone 8 | puts b 9 | -------------------------------------------------------------------------------- /type_restriction/type_restriction.cr: -------------------------------------------------------------------------------- 1 | class Foo; end 2 | class Bar < Foo; end 3 | class Cux < Foo; end 4 | class MyClass 5 | def initialize(@foo : Foo) 6 | end 7 | end 8 | 9 | 10 | MyClass.new(Foo.new) 11 | bar = Bar.new 12 | MyClass.new(bar) 13 | MyClass.new(Cux.new) 14 | -------------------------------------------------------------------------------- /url-parsing/url-parsing.cr: -------------------------------------------------------------------------------- 1 | require "uri" 2 | require "http/params" 3 | 4 | uri = URI.parse "postgres://user:pass@host.com:5432/path?k=v#f" 5 | p uri 6 | p uri.scheme # postgres 7 | p uri.user # user 8 | p uri.password # pass 9 | p uri.host # host.com 10 | p uri.port # 5432 11 | p uri.path # /path 12 | p uri.fragment # f 13 | p uri.query # k=v 14 | 15 | m = HTTP::Params.parse(uri.query.to_s) 16 | p m["k"] # v 17 | -------------------------------------------------------------------------------- /values/values.cr: -------------------------------------------------------------------------------- 1 | puts "crystal" + " " + "programming" 2 | 3 | puts "1+1 = #{1 + 1}" 4 | puts "7.0/3.0 = #{7.0 / 3.0}" 5 | 6 | puts true && false 7 | puts true || false 8 | puts !true 9 | -------------------------------------------------------------------------------- /variables/variables.cr: -------------------------------------------------------------------------------- 1 | a = "initial" 2 | puts a 3 | a = 3 4 | puts a 5 | 6 | # Currently type restrictions are not allowed for local variables 7 | # so we need the next few examples in a class 8 | 9 | class WrapperClass 10 | @x : String 11 | @e : Int32 12 | @y : Int32 | String 13 | 14 | def initialize 15 | @x = "osman" 16 | puts @x 17 | 18 | @e = 1 19 | puts @e 20 | 21 | # @e = "osman" 22 | # in ./variables/variables.cr:20: instance variable '@e' of WrapperClass must be Int32, not String 23 | @y = 1 24 | @y = "osman" 25 | puts @y 26 | end 27 | end 28 | 29 | WrapperClass.new 30 | 31 | # Multiple assignments in a single line 32 | b, c = 1, 2 33 | puts b, c 34 | 35 | d = true 36 | puts d 37 | -------------------------------------------------------------------------------- /while/while.cr: -------------------------------------------------------------------------------- 1 | a = nil 2 | while true 3 | a = 1 4 | break 5 | end 6 | puts a # 1 7 | 8 | while true 9 | b = 1 10 | break 11 | end 12 | puts b #  1 13 | 14 | while c = 1 15 | break 16 | end 17 | puts c # 1 18 | -------------------------------------------------------------------------------- /worker-pools/worker-pools.cr: -------------------------------------------------------------------------------- 1 | def worker(id, jobs, results) 2 | while !jobs.closed? || !jobs.empty? 3 | j = jobs.receive 4 | puts "worker #{id} processing job #{j}" 5 | sleep 1 6 | results.send j*2 7 | end 8 | end 9 | 10 | jobs = Channel(Int32).new(10) 11 | results = Channel(Int32).new(10) 12 | 13 | (1..3).each do |w| 14 | spawn worker(w, jobs, results) 15 | end 16 | 17 | (1..9).each do |j| 18 | jobs.send j 19 | end 20 | 21 | jobs.close 22 | 23 | 9.times do 24 | p results.receive 25 | end 26 | --------------------------------------------------------------------------------