Crystal

create new Crystal project

crystal init app projName

run a test build

crystal run src/proj.cr

build with debug

crystal build src/proj.cr -o bin/poni --error-trace

build for production

crystal build src/proj.cr -o bin/proj --release

Shards

install dependencies

add to shard.yaml

dependencies:

  toka:

    github: Papierkorb/toka

shards install

YAML

open YAML file, parse data and turn into Hash

begin  file = File.open('path/to/yaml)  yaml = YAML.parse(file)  hash = yaml.as_hrescue  puts "cant open YAML file for reading"endputs hashputs hash.class

Strings

replace a string

puts "Have a good day".gsub("good", "bad")

// have a bad day

count # of instances

puts "carthage".count('a')

check if string is null

puts "".empty?

if string includes

if "horse".includes?("se") // True

Interpolation

a = 1b = 2"sum: #{a} + #{b} = #{a + b}" # => "sum: 1 + 2 = 3"

capitalize

s = "horse"s.capitalize # Horse

lowercase

s.downcase

uppercase

s.upcase

delete a character from string

s = "horse"s.delete("hor") # se

delete at specific index

s = "horse"s.delete_at(2)  # hose

User input


puts "Enter name"name = gets.not_nil!puts "name is #{name}"

Array / List

a = [1,2,3]

declare new array (must provide type of value)

a = [] of (Int32 / String / Char)

get size of array

puts myArray.size

create an array out of string

names = "John Bob Mary"puts names.split()

get last element

puts myArray[-1]

add element to array

myArray << 5

remove last value

puts myArray.pop

remove 1st value

puts myArray.shift

check if value exists

puts myArray.includes? 5

delete value

myArray.delete(5)

delete from index to index

puts myArray.delete_at(0,2)

sort array

puts myArray.sort

return unique values

puts myArray.uniq!

get values of array

myArray.each do |value|  puts valueend

define specific array element types

myArray = [1,2,3] of String | Int32  (only accept strings or integers)myArray = Array(Int32).new  (define new array)

Change Variable Type

string to integer

myInt = myString.to_i

to_s  (to string)

to_a (array)

to_h (hash)

to_json


Check if string / int / number

a = 1

a.is_a?(Int32)   # true

a.is_a?(String)  # false

a.is_a?(Number)  # true

a.is_a? (Int32 | String)  # true

a.is_a?(Array)

get variable type

puts typeof(var)

Hash / Dictionary

a = {"name": "bob}

declare empty hash

a = {} of String

another way

myHash = { "Name" => "Bob", "Age" => 32 }

parse a hash

myHash.each do | key, val |  puts key.to_s + ":" + val.to_send

get size of hash

myHash.size.to_s

has key or value?

myHash.has_key?("Name")myHash.has_value?("Bob")

get everything except a certain key

puts myHash.reject("Age")

get only values that are greater than 2

puts myHash.select {|key, val| val > 2}

delete key

myHash.delete("Name")

delete key if 

myHash.delete_if {|key, val| key.starts_with?("Nam")}
h = {"foo" => "bar"}
h.delete("foo") { |key| "#{key} not found" } # => "bar"

get key

h.fetch("foo", nil)        

XML to Hash

xml = <<-XML  <person id="1">    <firstName preferredName="Jane">Jehanne</firstname>    <lastName>Doe</lastname>  </person>XML
document = XML.parse(xml)
p! hash = XMLConverter.new(document).to_h# => {"person" => {"id" => "1", "firstName" => {"preferredName" => "Jane", :value => "Jehanne"}, "lastName" => "Doe"}}p! person = hash.not_nil!["person"]# => {"id" => "1", "firstName" => {"preferredName" => "Jane", :value => "Jehanne"}, "lastName" => "Doe"}p! first_name = person.as(Hash(String | Symbol, XMLConverter::Type))["firstName"]# => {"preferredName" => "Jane", :value => "Jehanne"}p! value = first_name.as(Hash(String | Symbol, XMLConverter::Type))[:value]# => "Jehanne"
p! value.as(String).upcase

Functions

def addNums(n1, n2)

  return n1 + n2

end

kwargs

def getSum(*vals)

  sum = 0

  vals.each do |val|

    sum += val

  end

  return sum

end

puts getSum 1,2,3,4,5

immutable function type (input):output

def getID(id: Int32) : Int32


Class


class Animal

  def initialize(name: String)

    puts "This is an animal"

    @name = name

  end

  

  def setName(name)

    @name = name

  end

  def getName

    @name

  end

File Handling

# use this path for our file

path = "example.txt"

# create a new file and open it in write mode

# other files with the same name will be overwritten

example_file = File.new path, "w"example_file.puts "Text inside file"

# now close the file

example_file.close

# check if it exists before opening

abort "file is missing", 1 if !File.file? path

# and read its content to a string

content = File.read pathputs content 

# or just open it for further operations

our_file = File.open path, "w"our_file.puts "Another line"our_file.close

Tuple

like array but cannot change once initiated

myTup = { "Bob", 52, 234 }

myTup.each do |val|

  puts val

end

Named Tuple

myTup = {name: "Bob", age: 54}

get Name

puts myTup[:name]

Range

(0..5).to_a  # [0,1,2,3,4,5]
(0...5).to_a  # [0,1,2,3,4], 3 dots excludes last

Conditionals

If / Then / Only If / Unless / When

a = 2 if some_condition

same as 

if some_condition

  a = 2

end


if !var puts "var is empty" end

if a.is_a?(String) && b.is_a?(Number)  
  # here a is a String and b is a Number
end

if name is 'joe'

  puts 'hello joe' 

elsif name is 'fred'    

  puts 'hello fred'

end


age = 12

if (age >= 5) && (age <=6)

  puts "kindergarten"

elsif (age >=7) && (age <=13)  

  puts "middle school"

else  

  puts "other"

end

Tuple

like array but cannot change once initiated

myTup = { "Bob", 52, 234 }

myTup.each do |val|

  puts val

end

Named Tuple

myTup = {name: "Bob", age: 54}

get Name

puts myTup[:name]

Range

(0..5).to_a  # [0,1,2,3,4,5]
(0...5).to_a  # [0,1,2,3,4], 3 dots excludes last

Conditionals

If / Then / Only If / Unless / When

a = 2 if some_condition

same as 

if some_condition

  a = 2

end


if !var puts "var is empty" end

if a.is_a?(String) && b.is_a?(Number)  
  # here a is a String and b is a Number
end

if name is 'joe'

  puts 'hello joe' 

elsif name is 'fred'    

  puts 'hello fred'

end


age = 12

if (age >= 5) && (age <=6)

  puts "kindergarten"

elsif (age >=7) && (age <=13)  

  puts "middle school"

else  

  puts "other"

end

Comparison

not equals
if var1 != var2


Unless

unless age > 4  puts "too young for school"else  puts "go to school"end

Case

case language 

  when "French", "french", "FR", "fr"      puts "bonjour" 

  else   

    puts "not sure"

exit

Until

until x >= 10   

  x += 1   

  puts x 

end

While

while x <= 10

  x += 1   

break if x >= 10 

end