Ruby
Some interesting ressources for the programming language ruby.
Books
Interesting
RVM SSL errors
Install again with:
rvm install 3.0.2 --with-openssl-dir=`brew --prefix openssl`
If you got You must recompile Ruby with OpenSSL support on Mac ARM (M1) you have to:
brew uninstall openssl@3
brew reinstall openssl@1.1
#open new shell
rvm reinstall "ruby-3.0.0" --with-openssl-dir=`brew --prefix openssl@1.1` --disable-binary
On arch you have to install openssl-1.0 and run:
PKG_CONFIG_PATH=/usr/lib/openssl-1.0/pkgconfig:/usr/lib/pkgconfig rvm install <ruby-version>
Merge hashes
# Turn a collection of hashes into a single one
{ "yellow" => "#FFBEOB" },
{ "orange" => "#FB5607" },
{ "pink" => "#FF006E" }
1. reduce ({},:merge)
#=>“"yellow"=>"#FFBEOB", "orange"=>"#FB5607", "pink"=>"#FF006E"}
{}.merge(hash1, hash2, hash3) # works as well
Useful functions
Some ruby functions:
truncate(recipe.description, length: 150)   # truncate
time_ago_in_words(recipe.created_at)        # date
pluralize(count, "apple")                   # pluralize if count > 1 to apples
Scripting
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'sqlite3'
end
# write ruby code below
...
Lambda composition
Combine lambda blocks together with  >> i.e. to create a new one like TAX_FEE = TAX >> FEE
# List of our individual pricing rules
TAX           = ->(val) { val + val*0.05 }
FEE           = ->(val) { val + 1 }
PREMIUM       = ->(val) { val + 10 }
DISCOUNT      = ->(val) { val * 0.90 }
ROUND_TO_CENT = ->(val) { val.round(2) }
# One presenter
PRESENT       = ->(val) { val.to_f }
# Pre-define some rule sets for some pricing scenarios
REGULAR_SET    = [FEE, TAX, ROUND_TO_CENT, PRESENT]
PREMIUM_SET    = [FEE, PREMIUM, TAX, ROUND_TO_CENT, PRESENT]
DISCOUNTED_SET = [FEE, DISCOUNT, TAX, ROUND_TO_CENT, PRESENT]
Now we can define a price calculator:
def apply_rules(rules:, base_price:)
  rules.inject(:>>).call(base_price)
end
Source: get-around.tech
Object lookup
module GildedRose
	DEFAULT_CLASS = Item
	SPECIALIZED_CLASSES = {
		'normal' => Normal,
		'Aged Brie' => Brie,
		'Backstage passes to a TAFKAL80ETC concert' => Backstage }
	def self.for(name, quality, days_remaining)
		(SPECIALIZED_CLASSES[name] || DEFAULT_CLASS)
			.new(quality, days_remaining)
	end
end
Match data
class MatchData
  alias_method :deconstruct, :to_a
  def deconstruct_keys(keys)
    named_captures.transform_keys(&:to_sym).slice(*keys)
  end
end
IP_REGEX = /
  (?<first_octet>\d{1,3})\.
  (?<second_octet>\d{1,3})\.
  (?<third_octet>\d{1,3})\.
  (?<fourth_octet>\d{1,3})
/x
'192.168.1.1'.match(IP_REGEX) in {
  first_octet: '198',
  fourth_octet: '1'
}
# => true
Source: dev.to/baweaver
Case for array items:
def process (input)
	case input
	in []
		:empty
	in [*] if input.all?(Order)
		:has_only_orders
	in [*] if input.all? (Payment)
		:has_only_payments
	else
end
Refinement
Extend/overwrite string behavior in module (specific scope)
module PatchedString
  refine String do
    def +(value)
      self << ", #{value}"
    end
  end
end
module RegularNamespace
  def self.append_strings(a, b)
    a + b
  end
end
module PatchedNamespace
  using PatchedString
  def self.append_strings(a, b)
    a + b
  end
end
RegularNamespace.append_strings("1", "2") # => "12"
PatchedNamespace.append_strings("1", "2") # => "1, 2"