I am wondering if variables and methods can be used before declaration in Ruby. Is there something like hoisting in JavaScript?
def calcArea
getWidth * getHeight
end
def getWidth
@w
end
def getHeight
@h
end
@w = 10
@h = 20
p calcArea
I am wondering if variables and methods can be used before declaration in Ruby.
Variables don't need to be declared in Ruby, so that part of the question doesn't make sense. Variables come into existence when they are first assigned, or, in the case of local variables, when their first assignment is parsed.
Methods are defined, not declared. A method definition is a piece of code just like any other piece of code. It needs to be executed to take effect. You cannot call a method that doesn't exist, and a method only exists after its definition has executed.
Is there something like hoisting in JavaScript?
No.
def calcArea getWidth * getHeight end def getWidth @w end def getHeight @h end @w = 10 @h = 20 p calcArea
This works just fine, but it has nothing to do with hoisting. You only call calcArea
after it has been defined, so that's perfectly okay. calcArea
calls getWidth
and getHeight
, but only when calcArea
itself gets called, which is after all methods have been defined, so that's okay. getWidth
and getHeight
access @w
and @h
, but again, at the point that getWidth
and getHeight
are called, @w
and @h
have already been assigned, so that's okay, too. (And even if they hadn't been assigned, accessing them is still not an error, accessing an non-existent instance variable just evaluates to nil
; obviously, you would then get a NoMethodError
for trying to call *
on nil
, but that's very different from getting a NameError
for a non-existent variable.)
Some notes on coding style:
snake_case
for methods, parameters, local variables, instance variables, class variables, and global variables.get
prefix for getters.calcArea
is basically a getter for the area, so it, too, should be named without a prefix.So, according to Ruby community style, your code should look like this:
def area
width * height
end
def width
@width
end
def height
@height
end
@width = 10
@height = 20
p area
If this were part of a module or class definition, then you could use attr_reader
to auto-generate the getters, and attr_writer
to generate setters:
class Rectangle
attr_reader :width, :height
def area
width * height
end
private
attr_writer :width, :height
def initialize(width, height)
self.width, self.height = width, height
end
end
rect = Rectangle.new(10, 20)
p rect.area
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With