Some Ruby concepts explained for .net developers
I'm normally a .net developer, it's been my bread and butter for the past seven years and will be for several more. But it's also important for me to keep in touch with other languages out there, including Ruby. Here's my personal cheat sheet to remember naming conventions.
Method Names
are lower case and use underscores, as do Method Arguments
. The result of the last expression is automatically returned - there is no direct equivalent of void
, although nil
can serve that purpose.
def my_method(some_argument)
1 + 1 # implicitly returns 2.
end
Local Variables
are also lower case with underscores, and no special var
keyword is required to declare them.
def some_method
my_variable = 2
1 + my_variable
end
Instance Variables
- that is, a non-static field in a class - are prefixed with @
. Somewhat surprisingly, they can be declared within a method.
class MyClass
def do_stuff
@test = 4
end
def testing
2 + @test
end
end
myc = MyClass.new
puts myc.do_stuff
puts myc.testing
This outputs 4
and 6
. If I remove the puts myc.do_stuff
line, this throws an error: test.rb:8:in '+': nil can't be coerced into Fixnum (TypeError)
.
Constructors
are methods called initialize:
class MyClass
def initialize(initial_value)
@test = initial_value
end
def testing
return 2 + @test
end
end
myc = MyClass.new(3)
puts myc.testing
This outputs 5. Instance Variables are private by default, but Ruby has three special ways to declare a variable as public: attr_accessor
, attr_reader
and attr_writer
. Changing the class to this:
class MyClass
attr_reader :test
# .. rest as above
end
myc = MyClass.new(3)
puts myc.test # outputs 3
myc.test = 4 # undefined method 'test='
So attr_reader
is like public dynamic Test { get; private set; }
in .net, while attr_writer
is like { private get; set; }
and attr_accessor
is like { get; set; }
.
To create property getters and setters, just create methods. In the end, that is what attr_reader
etc. are doing, just like the .net auto-property syntax creates actual methods on compilation.
def test=(value)
puts "I'm a property setter for @test!"
@test = value
end
def test
puts "I'm a property getter for @test!"
return @test
end
Supposedly, attr_
methods are faster than manually implementing methods - not sure if it's true, but they are definitely the recommended way if you don't need actual logic in your getters and setters.
The syntax above used a Ruby symbol
, as evidenced by the colon - :test
. This is the concept that I took the longest to figure out. In a way, symbols are like interned strings in .net, since the same symbol will always mean the same thing whereas instances of strings may not be reference equal despite having the same content. Generally, Symbols should be seen as constant identifiers (they are in fact immutable). I recommend this blog post for some more information, but interned string
seems to be the best .net analogue I could come up with.
Class Variables
are static properties. In method names, self.
is the equivalent of a static method. There are some caveats when inheriting with regards to static properties.
class MyClass
@@static_var = 8
def initialize(my_value)
@instance_var = my_value
end
def testing
@instance_var + @@static_var
end
def self.static_var=(value)
@@static_var = value
end
end
myc = MyClass.new(3)
puts myc.testing # 11
myc2 = MyClass.new(4)
puts myc2.testing # 12
MyClass.static_var = 10
puts myc.testing # 13
puts myc2.testing # 14
Constants
are not prefixed and use SCREAMING_CAPS syntax.
class MyClass
MY_CONSTANT = 20
def testing
4 + MY_CONSTANT
end
end
myc = MyClass.new
puts myc.testing # 24
Class Inheritance uses < BaseClass
syntax. Like .net, Ruby does not support multiple inheritance but unlike .net, there are no interfaces.
class MyClass
def initialize
@test = 4
end
end
class MyDerivedClass < MyClass
def testing
2 + @test
end
end
myc = MyDerivedClass.new
puts myc.testing # 6
Modules
in Ruby are a bit like single-namespace assemblies in .net. Modules can contain Constants, methods, classes, etc. The include
keyword is like using
in .net.
module MyModule
SOME_CONSTANT = 20
def MyModule.say_hello
puts "Hello!"
end
end
class MyClass
include MyModule
def testing
MyModule.say_hello
4 + SOME_CONSTANT
end
end
myc = MyClass.new
puts myc.testing # Hello!, followed by 24
Modules do not support inheritance, despite them being like classes (in fact, Ruby's class
class inherits from the Module
class, which inherits from Object
). What's somewhat noteworthy is that constants do not need the Module name, unless there is something "closer" in scope.
class MyClass
include MyModule
SOME_CONSTANT = 30
def testing
puts 4 + SOME_CONSTANT # 34
puts 4 + MyModule::SOME_CONSTANT # 24
end
end
The double colon (::) was described as the namespace resolution operator on Stack Overflow.
There is obviously a lot more to Ruby that doesn't translate 1:1 to .net, but I hope that the above code samples make it a bit easier to understand Ruby as a .net developer