obj = Object.new def obj.talk puts "I am an object." puts "I can talk" end
Sending message to objects
object.message
In the context of this construct:
obj.talk
I am an object. I can talk
Methods that take arguments
In a method definition, you indicate the required and/or optional arguments by
means of a list of variables in (sometimes optional) parentheses after the method.
def obj.c2f(c) c * 9 / 5 + 32 end --------------------------------------------------------------------------- puts obj.c2f(100) = 212
Even a newly created object isn’t a blank slate.
p Object.new.methods.sort [:!, :!=, :!~, :<=>, :==, :===, :__id__, :__send__, :class, :clone, :define_singleton_method, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :inspect, :instance_eval, :instance_exec, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :methods, :nil?, :object_id, :pretty_inspect, :pretty_print, :pretty_print_cycle, :pretty_print_inspect, :pretty_print_instance_variables, :private_methods, :protected_methods, :public_method, :public_methods, :public_send, :remove_instance_variable, :respond_to?, :send, :singleton_class, :singleton_method, :singleton_methods, :tap, :then, :to_enum, :to_s, :yield_self]
obj = Object.new puts "The id of obj is #{obj.object_id}." 3.2.2 :093 > a = Object.new => #<Object:0x00007f3440f72670> 3.2.2 :094 > b = a => #<Object:0x00007f3440f72670> 3.2.2 :095 > a.id 3.2.2 :096 > a.object_id => 1844620 3.2.2 :097 > b.object_id => 1844620 --------------------------------------------- 3.2.2 :098 > string_1 = "Hello" => "Hello" 3.2.2 :099 > string_2 = "Hello" => "Hello" 3.2.2 :100 > string_1.object_id => 1906760 3.2.2 :101 > string_2.object_id => 1916160
obj = Object.new if obj.respond_to?("talk") obj.talk else puts "Sorry, the object doesn't understand the 'talk' message." end
if obj.respond_to?(request) obj.send(request) else puts "Object doesn't respond to message" end
def obj.one_arg(x) end obj.one_arg(1,2,3) results in: ArgumentError: wrong number of arguments (3 for 1)
It’s possible to write a method that allows a variable number of arguments.
def obj.multi_args(*x) end
And the mix of them:
def two_or_more(a, b, *c); end
Default values for arguments
def default_args(a,b,c=1) puts "Values of variables: ", a,b,c end
Argument type(s) | Method signature | Sample call(s) | Variable assignments |
---|---|---|---|
Required (Req) | def m(a,b,c) | m(1,2,3) | a = 1, b =2, c = 3 |
Optional (Opt) | def m(*a) | m(1,2,3) | a = [1,2,3] |
Default-valued (Def) | def m(a=1) | m / m(2) | a = 1 / a=2 |
Req/Opt | def m(a,*b) | m(1) | a = 1, b = [] |
Req/Def | def m(a,b=1) | m(2) / m(2,3) | a = 2, b = 1 / a = 2, b = 3 |
Def/Opt | def m(a=1, *b) | m / m(2) | a = 1, b = [] / a = 2, b = [] |
Req/Def/Opt | def m(a, b=2, *c) | m(1) / m(1,3) / m(1,3,5,7) | a=1, b=2, c=[] / a=1, b=3, c=[] / a = 1, b = 3, c = [5,7] |
In Ruby, local variables are created by simply assigning a value to them. They start with a lowercase letter or an underscore (_), followed by alphanumeric characters or underscores. Here's an example of local variable assignment:
# Variable assignment name = "John" age = 30
In this example, name and age are local variables. name holds the string value "John", and age holds the integer value 30.
Local variables in Ruby have a lexical scope, meaning they are accessible within the block of code in which they are defined, including any nested blocks. However, they are not accessible outside of their scope. For example:
def my_method x = 10 puts x # This will print 10 end my_method puts x # This will raise an error because `x` is not defined in this scope
In this example, x is a local variable defined within the scope of the my_method method. It is accessible within that method but not outside of it.
It's important to note that Ruby is dynamically typed, so the type of a variable is determined at runtime based on the value assigned to it. You can reassign a different value to a local variable:
x = 10 puts x # Output: 10 x = "hello" puts x # Output: hello
In this example, x is first assigned the integer value 10, and later it's reassigned the string value "hello". Ruby allows such dynamic variable assignment.
Local variables can come into being in either of two ways:
Here’s how Ruby decides what it’s seeing when it encounters a bareword:
1 If there’s an equal sign ( = ) to the right of the bareword, it’s a local variable
undergoing an assignment.
2 If the bareword is a keyword, it’s a keyword (Ruby has an internal list of
these and recognizes them).
3 Otherwise, the bareword is assumed to be a method call.
In Ruby, classes are blueprints for creating objects (instances). Each class defines the behavior and attributes that its instances will have. Here's an example of defining a class and creating instances of that class:
class Person def initialize(name, age) @name = name @age = age end def greet puts "Hello, my name is #{@name} and I'm #{@age} years old." end end # Creating instances of the Person class person1 = Person.new("Alice", 30) person2 = Person.new("Bob", 25) # Calling methods on instances person1.greet # Output: Hello, my name is Alice and I'm 30 years old. person2.greet # Output: Hello, my name is Bob and I'm 25 years old.
Explanation:
- We define a class Person using the class keyword.
- Inside the class, we define an initialize method. This method is a special method in Ruby classes and is called automatically when a new instance of the class is created (Person.new). It initializes the instance variables @name and @age.
- We define a greet instance method within the class. This method prints a greeting message using the instance variables @name and @age.
- We create two instances of the Person class (person1 and person2) using the new method. We pass arguments to the initialize method to set the name and age attributes for each instance.
- We call the greet method on each instance to print the greeting message specific to each person. In Ruby, instance variables (prefixed with @) are used to store data that belongs to each instance of a class. Instance methods can access and manipulate these instance variables to perform actions specific to each instance.
Instance methods
In Ruby, an instance method is a method that belongs to an instance of a class. These methods can access and modify the instance variables of the object on which they are called. Here's an example of defining and using an instance method in Ruby:
class Person def initialize(name, age) @name = name @age = age end # Instance method def greet puts "Hello, my name is #{@name} and I'm #{@age} years old." end end # Creating an instance of the Person class person = Person.new("Alice", 30) # Calling the instance method person.greet # Output: Hello, my name is Alice and I'm 30 years old.
Explanation:
Singletone methods
In Ruby, singleton methods are methods that are defined on individual objects rather than on the class itself. They are sometimes referred to as "singleton methods" because they are specific to a single object instance. Here's an example:
# Define a class class Dog end # Create an instance of the class dog = Dog.new # Define a singleton method on this instance def dog.bark puts "Woof!" end # Call the singleton method dog.bark # Output: Woof!
Explanation:
Singleton methods can also be defined using the define_singleton_method method:
dog.define_singleton_method(:jump) do puts "Jumping!" end dog.jump # Output: Jumping!
In this example, define_singleton_method is called on the dog instance to define a singleton method jump. This method will behave exactly like the previous example.
Redefining methods
class C def m puts "First definition of method m" end def m puts "Second definition of method m" end end C.new.m # Output: Second definition of method m
Reopening classes
class C # class code here end class C def x end end class C def y end end equivalent: class C def x end def y end end
Instance variables and object state
Information and data associated with a particular object is called the state of
the object. We need to be able to do the following:
Instance variables
The instance variable enables individual objects to remember state. Instance variables
work much like other variables: You assign values to them, and you read
those values back; you can add them together, print them out, and so on. However,
instance variables have a few differences.
- Instance variable names always start with @ (the at sign). This enables you to recognize an instance variable at a glance.
- Instance variables are only visible to the object to which they belong.
- An instance variable initialized in one method definition, inside a particular class, is the same as the instance variable of the same name referred to in other method definitions of the same class.
class C def inst_var_init(value) puts "Setting an instance variable...." @ivar = value end def inst_var_report puts "Inspecting the value of the instance variable...." puts @ivar end end c = C.new c.inst_var_init("Just some string") c.inst_var_report
In Ruby, instance variables are used to store the state of an object. Each instance of a class has its own set of instance variables, and they are not shared among different instances of the same class. Here's an example to illustrate instance variables and object state:
class Person def initialize(name, age) @name = name @age = age end def introduce puts "Hello, my name is #{@name} and I'm #{@age} years old." end def birthday @age += 1 puts "Happy birthday! Now I'm #{@age} years old." end end # Creating an instance of the Person class person1 = Person.new("Alice", 30) # Calling instance methods to access and modify object state person1.introduce # Output: Hello, my name is Alice and I'm 30 years old. person1.birthday # Output: Happy birthday! Now I'm 31 years old. # Creating another instance of the Person class person2 = Person.new("Bob", 25) # The state of person2 is independent of person1 person2.introduce # Output: Hello, my name is Bob and I'm 25 years old.
Explanation:
Initializing an object with state
In Ruby, you can initialize an object with state by defining an initialize method within the class. This method is automatically called when a new object is created using the new method. Here's an example:
class Person def initialize(name, age) @name = name @age = age end def introduce puts "Hello, my name is #{@name} and I'm #{@age} years old." end end # Creating an instance of the Person class with initial state person = Person.new("Alice", 30) # Calling instance methods to access the object state person.introduce # Output: Hello, my name is Alice and I'm 30 years old.
Explanation:
In Ruby, setter methods are used to set the values of instance variables of an object. They are typically defined using the convention of appending an equal sign (=) to the method name. Setter methods allow you to control how values are assigned to object attributes and can include validation or additional logic.
Here's a basic example of a setter method in Ruby:
class Person def initialize(name) @name = name end # Setter method for the 'name' attribute def name=(new_name) @name = new_name end # Getter method for the 'name' attribute def name @name end end person = Person.new("John") puts person.name # Output: John person.name = "Jane" # This calls the setter method
In this example, name= is the setter method for the name attribute of the Person class. It allows you to change the value of the name attribute by assigning a new value to it. The setter method takes one argument (new_name) which is the new value to be assigned to the name attribute.
Setter methods provide a way to encapsulate the logic for assigning values to object attributes, allowing you to control access to those attributes and add validation or additional behavior if needed.
In Ruby, the attr_* family of methods provide a convenient way to define getter and setter methods for object attributes. These methods help reduce boilerplate code by automatically creating accessor methods for instance variables. There are several variations of the attr_* methods:
class Person # Creates a getter method for the 'name' attribute attr_reader :name # Creates a setter method for the 'name' attribute attr_writer :name # Creates both getter and setter methods for the 'age' attribute attr_accessor :age def initialize(name, age) @name = name @age = age end end person = Person.new("John", 30) # Using getter method puts person.name # Output: John # Using setter method person.name = "Jane" puts person.name # Output: Jane # Using getter and setter methods created by attr_accessor puts person.age # Output: 30 person.age = 35 puts person.age # Output: 35
In this example, attr_reader :name creates a getter method for the name attribute, attr_writer :name creates a setter method for the name attribute, and attr_accessor :age creates both getter and setter methods for the age attribute.
Using attr_* methods provides a concise and readable way to define attributes and their accessor methods in Ruby classes.
To replay you need to login. Don't have an account? Sign up for one.