Ruby cheatsheet for pythonistas
In a shallow but long yak shaving streak, I ended up learning Ruby (again). Coming from a deep Python background (but also Perl and others), I sat to write down a cheatsheet so I can come back to it time and again:
module Foo # this is the root of this namespace # everything defined here must be referenced as Foo::thing, as in Foo::CamelCase::real_method() :symbol # symbols are the simplest objects, wich only have a name and a unique value :'symbol with spaces!' "#{interpolated_expression}" # how to iterpolate expressions in strings /regular_expression/ # very Perl-ish generator { |item| block } # this is related to yield %q{quote words} # à la perl! %w{words} # same? def classless_method_aka_function(default=:value) # Ruby calls these methods too block # ruby custom indents by 2! end method_call :without :parens class CamelCase < SuperClass # simple inheritance include Bar # this is a mixin; # Bar is a module and the class 'inherits' all its 'methods' public :real_method, :assign_method= protected :mutator_method! private :query_method? self # here is the class! def real_method(*args) # splat argument, can be anywhere # no **kwargs? super # this calls SuperClass::real_method(*args) # comapre with super() # this calls SuperClass::real_method()! local_variable @instance_variable # always private @@class_variable # always private $global_variable return self # alternatively self # as the implicit return value is the last statement executed # and all statements produce a value end def assign_method=() # conventionally for this kind of syntactic sugar: # When the interpreter sees the message "name" followed by " =", # it automatically ignores the space before the equal sign # and reads the single message "name=" - # a call to the method whose name is name= end class << self # this is in metaclass context! end protected def mutator_method!(a, *more, b) # conventionally this modifies the instance end private def query_method?() # conventionally returns true/false end end # extending classes class CamelCase # do I need to respecify the inheritance here? def more_methods () end end obj.send(:method_name_as_symbol, args, ...) begin raise 'exceptions can be strings' rescue OneType => e # bind the exception to e # rescued rescue AnotherType # also ensure # finally else # fallback end =begin Long comment blocks! =end statement; statement long \ line # everything is true except false # and nil variable ||= default_value `shell` AConstant # technically class names are constants # so do module names A_CONSTANT # conventionally; always public # The Ruby interpreter does not actually enforce the constancy of constants, # but it does issue a warning if a program changes the value of a constant # case is an expression foo = case when true then 100 when false then 200 else 300 end do |args; another_local_variable| # args are local variables of this block # whose scope ends with the block # and which can eclipse another variable of the same name # in the containing scope # another_local_variable is declared local but does not # consume parameters end { |args| ... } # another block, conventionally single lined # Matz says that any method can be called with a block as an implicit argument. # Inside the method, you can call the block using the yield keyword with a value. # Matz is Joe Ruby # yield is not what python does # see http://rubylearning.com/satishtalim/ruby_blocks.html # block_given? a= [] # array a[^0] == nil ENV # hash holding envvars ARGV # array with CL arguments (1..10) # range (0...10) # python like 5 === (1..10) # true, 'case equality operator' { :symbol => 'value' } == { symbol: 'value' } # hashes, not blocks :) lambda { ... } # convert a block into a Proc object # you cannot pass methods into other methods (but you can pass Procs into methods), # and methods cannot return other methods (but they can return Procs). load 'foo.rb' # #include like require 'foo' # import, uses $: require_relative 'bar' # import from local dir
It's not complete; in particular, I didn't want to go into depth on what yield
does (hint: not what does in Python). I hope it's
useful to others. I strongly recommend to read this tutorial.
Also, brace yourselves; my impression is that Ruby is not as well documented as we're used in Python.