Fork me on GitHub

Language compare

Ruby

Python

String

Create

greeting = 'Hello World!'
puts greeting
Hello World!
greeting = 'Hello World!'
print(greeting)
Hello World!

Concatenation

puts "Don't worry," + ' be happy'
Don't worry, be happy
print("Don't worry," + ' be happy')
Don't worry, be happy

Interpolation

first = "Don't worry,"
second = 'be happy'
puts "#{first} #{second}"
Don't worry, be happy
first = "Don't worry,"
second = 'be happy'
print('%s %s' % (first, second))
Don't worry, be happy
<span class='small'>[ 3.6 ]</span><div class="highlight"><pre class="highlight python"><code><span class="n">first</span> <span class="o">=</span> <span class="s">"Don't worry,"</span> <span class="n">second</span> <span class="o">=</span> <span class="s">'be happy'</span> <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'</span><span class="si">{</span><span class="n">first</span><span class="si">}</span><span class="s"> </span><span class="si">{</span><span class="n">second</span><span class="si">}</span><span class="s">'</span><span class="p">)</span> </code></pre></div>
Don't worry, be happy

Remove part

puts 'This is not funny! I am not like him!'.gsub('not ', '')
This is funny! I am like him!
print('This is not funny! I am not like him!'.replace('not ', ''))
This is funny! I am like him!

Replace

puts 'You should work'.gsub('work', 'rest')
You should rest
print('You should work'.replace('work', 'rest'))
You should rest

Split

puts 'I like beer'.split
I
like
beer
print('I like beer'.split())
['I', 'like', 'beer']

Remove leading and trailing whitespace

puts ' eh? '.strip
eh?
print(' eh? '.strip())
eh?

Compare

puts 'string' == 'string'
puts 'string' != 'string'
true
false
print('string' == 'string')
print('string' != 'string')
True
False

Regex

p 'apple' =~ /^b/
p 'apple' =~ /^a/
nil
0
import re

print(re.search('^b', 'apple'))
print(re.search('^a', 'apple'))
None
<re.Match object; span=(0, 1), match='a'>

Number

Increment

i = 9
i += 1
puts i
10
i = 9
i += 1
print(i)
10

Compare

puts 1 < 2 && 2 < 3
puts 5 == 5
puts 5 != 5
true
true
false
print(1 < 2 < 3)
print(5 == 5)
print(5 != 5)
True
True
False

Random

puts rand(1..2)
1
import random

print(random.randint(1, 2))
2

Float

puts 9 / 2
puts 9 / 2.0
puts (9 / 2.0).floor
puts (9 / 2.0).round
4
4.5
4
5
import math

print(9 // 2)
print(9 / 2)
print(math.floor(9 / 2))
print(round(9 / 2))  # rounds half to even
4
4.5
4
4

Type

Get type of object

puts 'hi'.class
puts 1.class
String
Fixnum
print(type('hi'))
print(type(1))
<class 'str'>
<class 'int'>

Int to Float

puts 10.to_f
10.0
print(float(10))
10.0

Int to String

puts 10.to_s
10
print(str(10))
10

String to Int

puts '5'.to_i
5
print(int('5'))
5

String?

puts '10'.is_a? String
true
print(isinstance('10', str))
True

Null/True/False?

def check(label, fn, values)
  puts label
  values.each do |value|
    begin
      result = fn.call(value) ? 'true' : 'false'
    rescue NoMethodError => e
      result = "error: #{e}"
    end
    puts format("  %-9p - %s", value, result)
  end
  puts ''
end

values = ['string', '', [1, 2, 3], [], 5, 0, true, false, nil]

check('if value:', -> (v) { v }, values)
check('if value.nil?:', -> (v) { v.nil? }, values)
check('if value.empty?:', -> (v) { v.empty? }, values)
if value:
  "string"  - true
  ""        - true
  [1, 2, 3] - true
  []        - true
  5         - true
  0         - true
  true      - true
  false     - false
  nil       - false

if value.nil?:
  "string"  - false
  ""        - false
  [1, 2, 3] - false
  []        - false
  5         - false
  0         - false
  true      - false
  false     - false
  nil       - true

if value.empty?:
  "string"  - false
  ""        - true
  [1, 2, 3] - false
  []        - true
  5         - error: undefined method `empty?' for 5:Fixnum
  0         - error: undefined method `empty?' for 0:Fixnum
  true      - error: undefined method `empty?' for true:TrueClass
  false     - error: undefined method `empty?' for false:FalseClass
  nil       - error: undefined method `empty?' for nil:NilClass

def check(label, fn, values):
    print(label)
    for value in values:
        try:
            result = 'true' if fn(value) else 'false'
        except TypeError as e:
            result = 'error: %s' % e
        print("  %-9r - %s" % (value, result))
    print()

values = ['string', '', [1, 2, 3], [], 5, 0, True, False, None]

check('if value:', lambda v: v, values)
check('if value is None:', lambda v: v is None, values)
check('if len(value):', lambda v: len(v), values)
if value:
  'string'  - true
  ''        - false
  [1, 2, 3] - true
  []        - false
  5         - true
  0         - false
  True      - true
  False     - false
  None      - false

if value is None:
  'string'  - false
  ''        - false
  [1, 2, 3] - false
  []        - false
  5         - false
  0         - false
  True      - false
  False     - false
  None      - true

if len(value):
  'string'  - true
  ''        - false
  [1, 2, 3] - true
  []        - false
  5         - error: object of type 'int' has no len()
  0         - error: object of type 'int' has no len()
  True      - error: object of type 'bool' has no len()
  False     - error: object of type 'bool' has no len()
  None      - error: object of type 'NoneType' has no len()

Array

Create populated

arr = %w(first second)
puts arr
first
second
arr = ['first', 'second']
print(arr)
['first', 'second']

Add

arr = []
arr.push 'first'
arr.push 'second'
puts arr
first
second
arr = []
arr.append('first')
arr.append('second')
print(arr)
['first', 'second']

With different types

puts ['first', 1]
first
1
print(['first', 1])
['first', 1]

Include?

puts [1, 2].include? 1
true
print(1 in [1, 2])
True

Iterate

[1, 2].each do |num|
  puts num
end
1
2
for num in [1, 2]:
  print(num)
1
2

Iterate with index

%w(one two).each_with_index do |num, i|
  puts num
  puts i
end
one
0
two
1
for i, num in enumerate(['one', 'two']):
  print(num)
  print(i)
one
0
two
1

Get first, last element

arr = %w(one two)
puts arr.first
puts arr.last
one
two
arr = ['one', 'two']
print(arr[0])
print(arr[-1])
one
two

Find first

arr = [1, 5, 10, 20]
puts arr.find(&:even?)
10
arr = [1, 5, 10, 20]
print(next(i for i in arr if i % 2 == 0))
10

Select (find all)

arr = [1, 5, 10, 20]
puts arr.select(&:even?)
10
20
arr = [1, 5, 10, 20]
print([i for i in arr if i % 2 == 0])
[10, 20]

Map (change all)

arr = [1, 5, 10, 20]
puts arr.map { |num| num * 2 }
2
10
20
40
arr = [1, 5, 10, 20]
print([num * 2 for num in arr])
[2, 10, 20, 40]

Concatenation

puts [1, 2] + [3, 4]
1
2
3
4
print([1, 2] + [3, 4])
[1, 2, 3, 4]

Sort

puts [4, 2, 3, 1].sort
1
2
3
4
print(sorted([4, 2, 3, 1]))
[1, 2, 3, 4]

Multidimensional

multi = [%w(first second), %w(third forth)]
puts multi[1][1]
forth
multi = [['first', 'second'], ['third', 'forth']]
print(multi[1][1])
forth

Size

puts [1, 2, 3].size 
3
print(len([1, 2, 3]))
3

Count

arr = [1, 11, 111]
puts arr.count { |i| i > 10 }
2
arr = [1, 11, 111]
print(sum(1 for i in arr if i > 10))
2

Reduce

puts [1, 2, 3].reduce(:+)
6
import functools, operator

print(functools.reduce(operator.add, [1, 2, 3]))
print(sum([1, 2, 3]))  # a more Pythonic example
6
6

Index of element

puts ['a', 'b', 'c'].index('c')
2
print(['a', 'b', 'c'].index('c'))
2

Delete element

arr = %w(a b c)
arr.delete('b')
puts arr
a
c
arr = ['a', 'b', 'c']
arr.remove('b')
print(arr)
['a', 'c']

Unique

puts %w(a b a).uniq
a
b
print(set(['a', 'b', 'a']))
{'a', 'b'}

Hash (map)

Create populated

options = { font_size: 10, font_family: 'Arial' }
puts options
{:font_size=>10, :font_family=>"Arial"}
options = {'font_size': 10, 'font_family': 'Arial'}
print(options)
{'font_size': 10, 'font_family': 'Arial'}

Add

options = {}
options[:font_size] = 10
options[:font_family] = 'Arial'
puts options
{:font_size=>10, :font_family=>"Arial"}
options = {}
options['font_size'] = 10
options['font_family'] = 'Arial'
print(options)
{'font_size': 10, 'font_family': 'Arial'}

Iterate

{ font_size: 10, font_family: 'Arial' }.each do |key, value|
  puts key, value
end
font_size
10
font_family
Arial
for key, value in {'font_size': 10, 'font_family': 'Arial'}.items():
  print(key, value)
font_size 10
font_family Arial

Include?

options = { font_size: 10, font_family: 'Arial' }
puts options.include? :font_size
true
options = {'font_size': 10, 'font_family': 'Arial'}
print('font_size' in options)
True

Get value

options = { font_size: 10, font_family: 'Arial' }
puts options[:font_size]
10
options = {'font_size': 10, 'font_family': 'Arial'}
print(options['font_size'])
10

Size

options = { font_size: 10, font_family: 'Arial' }
puts options.size
2
options = {'font_size': 10, 'font_family': 'Arial'}
print(len(options))
2

Other structure

Boolean

try_it = true
puts 'Garlic gum is not funny' if try_it
Garlic gum is not funny
try_it = True
if try_it:
    print('Garlic gum is not funny')
Garlic gum is not funny

Constant

COST = 100
COST = 50
puts COST
/Users/evmorov/projects/lang-compare/code/ruby/other_structure_constant.rb:2: warning: already initialized constant COST
/Users/evmorov/projects/lang-compare/code/ruby/other_structure_constant.rb:1: warning: previous definition of COST was here
50
COST = 100
COST = 50
print(COST)
50

Constant list

module Colors
  RED = '#FF0000'
  GREEN = '#00FF00'
end
puts Colors::GREEN
#00FF00
class Colors:
    RED = '#FF0000'
    GREEN = '#00FF00'

print(Colors.GREEN)
#00FF00

Struct

Customer = Struct.new(:name, :address) do
  def greeting
    "Hello #{name}!"
  end
end
puts Customer.new('Dave', '123 Main').greeting

Hello Dave!
import collections

class Customer(collections.namedtuple('Customer', 'name address')):
    def greeting(self):
        return "Hello %s!" % self.name

print(Customer('Dave', '123 Main').greeting())
Hello Dave!

Conditional

If

puts 'Hello' if true
Hello
if True:
    print('Hello')
Hello

Unless

angry = false
puts 'smile!' unless angry
smile!
angry = False
if not angry:
    print('smile!')
smile!

If/else

if true
  puts 'work'
else
  puts 'sleep'
end
work
if True:
  print('work')
else:
  print('sleep')
work

And/Or

puts 'no' if true && false
puts 'yes' if true || false
yes
if True and False:
    print('no')
if True or False:
    print('yes')
yes

Switch

foo = 'Hello!'
case foo
when 1..5
  puts "It's between 1 and 5"
when 10, 20
  puts '10 or 20'
when 'And' then puts 'case in one line'
when String
  puts "You passed a string '#{foo}'"
else
  puts "You gave me '#{foo}'"
end
You passed a string 'Hello!'
foo = 'Hello!'
if foo in range(1, 6):
    print("It's between 1 and 5")
elif foo in (10, 20):
    print('10 or 20')
elif foo == 'And':
    print('case in one line')
elif isinstance(foo, str):
    print("You passed a string %r" % foo)
else:
    print("You gave me %r" % foo)
You passed a string 'Hello!'

Switch as else if

score = 76
grade = case
        when score < 60 then 'F'
        when score < 70 then 'D'
        when score < 80 then 'C'
        when score < 90 then 'B'
        else 'A'
        end
puts grade
C
score = 76
grades = [
    (60, 'F'),
    (70, 'D'),
    (80, 'C'),
    (90, 'B'),
]
print(next((g for x, g in grades if score < x), 'A'))
C

Ternary

puts false ? 'no' : 'yes'
yes
print('no' if False else 'yes')
yes

If assign

result =
if true
  'a'
else
  'b'
end
puts result

a
result = 'a' if True else 'b'
print(result)
a

Loop

For

(1..3).each do |i|
  puts "#{i}. Hi"
end
1. Hi
2. Hi
3. Hi
for i in range(1, 4):
    print('%d. Hi' % i)
1. Hi
2. Hi
3. Hi

For with a step

(0..4).step(2) do |i|
  puts i
end
0
2
4
for i in range(0, 5, 2):
    print(i)
0
2
4

Times

3.times do
  puts 'Hi'
end
Hi
Hi
Hi
for i in range(3):
  print('Hi')
Hi
Hi
Hi

While

i = 0
while i < 3
  i += 1
end
puts i
3
i = 0
while i < 3:
  i += 1
print(i)
3

Until

i = 0
i += 1 until i == 3
puts i
3
i = 0
while i != 3:
    i += 1
print(i)
3

Return array

greetings = Array.new(3) do |i|
  "#{i + 1}. Hello!"
end
puts greetings
1. Hello!
2. Hello!
3. Hello!
greetings = ["%d. Hello!" % time for time in range(1, 4)]
print(greetings)
['1. Hello!', '2. Hello!', '3. Hello!']

Break

3.times do |time|
  puts "#{time + 1}. Hi"
  break if time == 1
end
1. Hi
2. Hi
for time in range(1, 4):
  print("%d. Hi" % time)
  if time == 2:
    break
1. Hi
2. Hi

Next/Continue

3.times do |time|
  next if time == 1
  puts "#{time + 1}. Hi"
end
1. Hi
3. Hi
for time in range(1, 4):
  if time == 2:
      continue
  print("%d. Hi" % time)
1. Hi
3. Hi

Math

Max/Min

arr = [1, 2, 3]
puts arr.min
puts arr.max
1
3
arr = [1, 2, 3]
print(min(arr))
print(max(arr))
1
3

Sqrt

puts Math.sqrt(9)
3.0
import math

print(math.sqrt(9))
3.0

Error handling

Try/catch/finally

begin
  1 / 0
rescue
  puts "Can't divide"
ensure
  puts "But that's ok"
end

1 / 0 rescue puts "Can't divide"
Can't divide
But that's ok
Can't divide
try:
  1 / 0
except:
  print("Can't divide")
finally:
  print("But that's ok")
Can't divide
But that's ok

With a message

begin
  1 / 0
rescue => e
  puts e.message
end
divided by 0
try:
  1 / 0
except Exception as e:
  print(e)
division by zero

Method

def divide(num1, num2)
  num1 / num2
rescue => e
  puts e.message
end
divide(1, 0)
divided by 0
def divide(num1, num2):
  try:
    num1 / num2
  except Exception as e:
    print(e)
divide(1, 0)
division by zero

Throw exception

begin
  fail 'An error!'
rescue => e
  puts e.message
end
An error!
try:
  raise Exception('An error!')
except Exception as e:
  print(e)
An error!

File

Read

file_path = File.join(Dir.getwd, 'code', 'file.txt')
puts File.read(file_path)
Hello
World
import os

with open(os.path.join(os.getcwd(), 'code', 'file.txt')) as f:
    print(f.read())
Hello
World

Write

file_path = File.join(File.dirname(__FILE__), 'output.txt')
File.write(file_path, 'Some glorious content')

import pathlib

with (pathlib.Path(__file__).parent / 'output.txt').open('w') as f:
    f.write('Some glorious content')

Get working dir path

puts Dir.getwd
/Users/evmorov/projects/lang-compare
import os

print(os.getcwd())
/Users/evmorov/projects/lang-compare

File path

puts __FILE__
/Users/evmorov/projects/lang-compare/code/ruby/file_path.rb
print(__file__)
/Users/evmorov/projects/lang-compare/code/python/file_path.py

Dir path

puts File.dirname(__FILE__)
/Users/evmorov/projects/lang-compare/code/ruby
import pathlib

print(pathlib.Path(__file__).parent)
/Users/evmorov/projects/lang-compare/code/python

Parent dir path

puts File.expand_path File.join(__FILE__, '..', '..')
/Users/evmorov/projects/lang-compare/code
import pathlib

print(pathlib.Path(__file__).parents[1])
/Users/evmorov/projects/lang-compare/code

Sister dir path

puts File.expand_path File.join(__FILE__, '..', '..', 'php')

/Users/evmorov/projects/lang-compare/code/php
import pathlib

print(pathlib.Path(__file__).parents[1] / 'ruby')
/Users/evmorov/projects/lang-compare/code/ruby

Method

Declare

def hey
  puts 'How are you?'
end
hey
How are you?
def hey():
  print('How are you?')
hey()
How are you?

Multiple arguments

def sweets(buy, *brands)
  puts brands if buy
end
sweets true, 'snickers', 'twix', 'bounty'
snickers
twix
bounty
def sweets(buy, *brands):
  if buy:
      print(brands)
sweets(True, 'snickers', 'twix', 'bounty')
('snickers', 'twix', 'bounty')

Default value for argument

def send(abroad = false)
  puts abroad ? 'Send abroad' : 'Send locally'
end
send
send true
Send locally
Send abroad
def send(abroad=False):
  print('Send abroad' if abroad else 'Send locally')
send()
send(True)
Send locally
Send abroad

Return

def multiple(a, b)
  a * b
end
puts multiple(2, 3)

def divide(a, b)
  return 0 if a == 0
  a / b
end
puts divide 0, 10

def default_value
end
p default_value
6
0
nil
def multiply(a, b):
    return a * b

def divide(a, b):
    return 0 if a == 0 else a / b

def default_value():
    pass

print(multiply(2, 3))
print(divide(0, 10))
print(default_value())
6
0
None

Closure

square = -> (x) { x * x }
puts [2, 3].map(&square)

greeting = -> { puts 'Hello World!' }
greeting.call
4
9
Hello World!
square = lambda x: x * x
print(list(map(square, [2, 3])))

greeting = lambda: print('Hello World!')
greeting()
[4, 9]
Hello World!

Block passing

def my_select(arr)
  selected = []
  arr.each do |a|
    selected.push a if yield(a)
  end
  selected
end
puts my_select [1, 5, 10] { |x| x < 6 }


def my_select(arr, &filter)
  selected = []
  arr.each do |a|
    selected.push a if filter.call(a)
  end
  selected
end
puts my_select [1, 5, 10] { |x| x < 6 }
1
5
1
5
def select(arr):
    yield from arr

def select_filter(arr, filter):
    for a in arr:
        if filter(a):
            yield a

print([x for x in select([1, 5, 10]) if x < 6])
print(list(select_filter([1, 5, 10], lambda x: x < 6)))
[1, 5]
[1, 5]

Block binding

class Action
  def self.say(&sentence)
    @name = 'Ann'
    puts sentence.call
  end
end

class Person
  def initialize(name)
    @name = name
  end

  def greet
    Action.say { "My name is #{@name}!" }
  end
end

Person.new('Alex').greet
My name is Alex!
class Action:
  name = 'Ann'

  @staticmethod
  def say(sentence):
    print(sentence())


class Person:
  def __init__(self, name):
    self.name = name

  def greet(self):
    Action.say(lambda: "My name is %s!" % self.name)


Person('Alex').greet()
My name is Alex!

Initialize in runtime

class ProccessElements
  def self.element(el_name)
    define_method "#{el_name}_element" do |content|
      "<#{el_name}>#{content}</#{el_name}>"
    end
  end
end

class HtmlELements < ProccessElements
  element :div
  element :span
end

puts HtmlELements.new.div_element('hello')
<div>hello</div>
class ProccessElements:
  def __init__(self):
    def element(el_name):
      def render(content):
        return '<{0}>{1}</{0}>'.format(el_name, content)
      return render

    for el_name in self.elements:
      setattr(self, el_name, element(el_name))


class HtmlELements(ProccessElements):
  elements = ('div', 'span')

print(HtmlELements().div('hello'))
<div>hello</div>

Alias

class Greetings
  def hey
    puts 'How are you?'
  end
  alias_method :hi, :hey
end

Greetings.new.hi
How are you?
class Greetings:
  def hey(self):
    print('How are you?')
  hi = hey

Greetings().hi()
How are you?

Class

Declare

class Animal
  def walk
    puts "I'm walking"
  end
end

Animal.new.walk
I'm walking
class Animal:
  def walk(self):
    print("I'm walking")

Animal().walk()
I'm walking

Constructor

class Animal
  def initialize(name)
    @name = name
  end

  def walk
    puts "My name is #{@name} and I'm walking"
  end
end

Animal.new('Kelya').walk
My name is Kelya and I'm walking
class Animal:
  def __init__(self, name):
    self.name = name

  def walk(self):
    print("My name is %s and I'm walking" % self.name)

Animal('Kelya').walk()
My name is Kelya and I'm walking

Method call

class Animal
  def walk
    bark
    guard
    puts "I'm walking"
  end

  def bark
    puts 'Wuf!'
  end

  private

  def guard
    puts 'WUUUF!'
  end
end

Animal.new.walk
Wuf!
WUUUF!
I'm walking
class Animal:
  def walk(self):
    self.bark()
    self._guard()
    print("I'm walking")

  def bark(self):
    print('Wuf!')

  # Private by convention
  def _guard(self):
    print('WUUUF!')

Animal().walk()
Wuf!
WUUUF!
I'm walking

Class method

class Animal
  def self.feed
    puts 'Om nom nom'
  end
end

Animal.feed
Om nom nom
class Animal:
  @classmethod
  def feed(cls):
    print('Om nom nom')

Animal.feed()
Om nom nom

Private method

class Animal
  def eat(food)
    puts 'Om nom nom' if meat? food
  end

  private

  def meat?(food)
    food == 'meat'
  end
end

Animal.new.eat('meat')
Om nom nom
class Animal:
  def eat(self, food):
    if self._is_meat(food):
      print('Om nom nom')

  def _is_meat(self, food):
    return food == 'meat'

Animal().eat('meat')
Om nom nom

Private method, access instance variable

class Animal
  def initialize(name)
    @name = name
    greet
  end

  private

  def greet
    puts "Hello! My name is #{@name}"
  end
end

Animal.new('Kelya')
Hello! My name is Kelya
class Animal:
  def __init__(self, name):
    self.name = name
    self._greet()

  def _greet(self):
    print("Hello! My name is %s" % self.name)

Animal('Kelya')
Hello! My name is Kelya

Field

class Animal
  def take(toy)
    @toy = toy
  end

  def play
    puts "I'm playing with #{@toy}"
  end
end

animal = Animal.new
animal.take('a ball')
animal.play
I'm playing with a ball
class Animal:
  def take(self, toy):
    self.toy = toy

  def play(self):
    print("I'm playing with %s" % self.toy)

animal = Animal()
animal.take('a ball')
animal.play()
I'm playing with a ball

Get/set

class Animal
  attr_accessor :name
end

animal = Animal.new
animal.name = 'Kelya'
puts animal.name
Kelya
class Animal:
  name = None

animal = Animal()
animal.name = 'Kelya'
print(animal.name)
Kelya

Inheritance

class Animal
  def walk
    puts "I'm walking"
  end
end

class Dog < Animal
  def sing
    puts 'Bark!'
  end
end

Dog.new.walk
I'm walking
class Animal:
  def walk(self):
    print("I'm walking")

class Dog(Animal):
  def sing(self):
    print('Bark!')

Dog().walk()
I'm walking

Mixin

module Moving
  def walk
    puts "#{self.class.name} is walking"
  end
end

module Interacting
  def talk
    puts "#{self.class.name} is talking"
  end
end

class Human
  include Moving
  include Interacting
end

human = Human.new
human.walk
human.talk
Human is walking
Human is talking
class Moving:
  def walk(self):
    print("%s is walking" % self.__class__.__name__)

class Interacting:
  def talk(self):
    print("%s is talking" % self.__class__.__name__)

class Human(Moving, Interacting):
    pass

human = Human()
human.walk()
human.talk()
Human is walking
Human is talking

Has method?

class Animal
  def walk
    puts "I'm walking"
  end
end

animal = Animal.new
puts animal.respond_to? :walk
true
class Animal:
  def walk(self):
    print("I'm walking")

animal = Animal()
print(hasattr(animal, 'walk'))
True

Other

Comment

# it's a comment

# it's a comment

Assign value if not exist

speed = 0
speed ||= 15
puts speed
0
speed = 0
speed = 15 if speed is None else speed
print(speed)
0

Safe navigation

class Winner
  attr_reader :address

  def initialize
    # @address = Address.new
  end
end

class Address
  attr_reader :zipcode

  def initialize
    @zipcode = 192187
  end
end

zip = Winner.new.address&.zipcode
puts zip ? "Zipcode is #{zip}" : "No prize without zipcode"
No prize without zipcode
No easy way to do that

Import another file

# other_file_to_import.rb
# class Import
#   def initialize
#     puts 'I am imported!'
#   end
# end

require_relative 'other_file_to_import'
Import.new
I am imported!
# other_file_to_import.py
# class Import:
#   def __init__(self):
#     print('I am imported!')

import other_file_to_import
other_file_to_import.Import()
I am imported!

Destructuring assignment

one, two = [1, 2]
puts one, two
1
2
one, two = 1, 2
print(one, two)
1 2

Date

require 'date'
puts Date.today
2024-05-28
import datetime
print(datetime.date.today())
2024-05-28

Time

puts Time.now
2024-05-28 20:17:54 +0200
import datetime
print(datetime.datetime.now())
2024-05-28 20:18:14.644332

Not

angry = false
puts 'smile!' if !angry
smile!
angry = False
if not angry:
  print('smile!')
smile!

Assign this or that

yeti = nil
footprints = yeti || 'bear'
puts footprints
bear
yeti = None
footprints = yeti or 'bear'
print(footprints)
bear

Run command

puts `ruby -v`
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin21]
import subprocess
subprocess.call(['python3', '--version'])
Python 3.11.2