⬆️ ⬇️

Let's beat Ruby together! Drop eight

Let's reread the fourth drop right now to recall the implementation of the PLO in Ruby. Repeat? Go ahead. In this drop, we will prune all the tails formed, related to object-oriented programming in Ruby.





new and initialize



Let's take another look at the code from the fourth drop:



 class Dog def set_name( aName ) @myname = aName end def get_name return @myname end def gav return 'rrrr!' end end dog1 = Dog.new dog1.set_name( 'Fido' ) puts(dog1.get_name) puts(dog1.gav) 


')

Similar program:



 class Dog def initialize(name, age) @name = name @age = age end def get_name return @name end def get_age return @age end end d = Dog.new('Fido', 2) puts "My name is #{d.get_name} and I'm #{d.get_age}" 




When a new class is defined (usually using a class Name ... end ), an object of type Class . When Name.new is Name.new to create a new object, the instance method is called new from Class , which in turn activates allocate to allocate memory for the object before the initialize method of the new object is called. The construction and initialization phases of the object are separate and can be rewritten. Initialization occurs through the instance method initialize , construction - through new . initialize is not a constructor (controversial, of course, but different sources show different opinions).



Using initialize has two distinct advantages over setting instance variables using methods like set_name . First of all, a complex class can contain multiple instance variables and all of them can be declared using a single line with initialize without having to write methods for each. Also, if all variables are declared during object creation (as written above immediately after new , initialize is called), you will never have undefined variables ( nil ).



Even easier



In the code, we defined two methods ( get_name and get_age ) to return two instance variables. Since this is a simple and frequently used idiom, Ruby provides a simplification: attr_reader will define these methods for us:



 class Dog attr_reader :name, :age def initialize(name, age) @name = name @age = age end end d = Dog.new("Fido", 2) puts "My name is #{d.name} and I'm #{d.age}" 




Note that in attr_reader , attr_reader are used (see the last drop) and how the query has changed the value in the output. attr_writer will define set methods ( set_name in the first listing, for example), and attr_accessor combines the capabilities of the reader and writer (see the example with the zoo in the fourth drop).



initialize + inheritance



In the fourth drop, we already talked about inheritance in the "zoo", but there we used attr_accessor . How inheritance will look if we refuse them and we will return to initialize and methods? Not much harder:



 class Pet def initialize(name, age) @name = name @age = age end def get_name return @name end def get_age return @age end end class Dog < Pet def initialize(name, age) @name = name @age = age super end end class Snake < Pet def initialize(name, age, length) @name = name @age = age @length = length super(name, age) end def get_length return @length end end d = Dog.new('Fido', 2) s = Snake.new('Lili', 2, 85) puts "Dog: My name is #{d.get_name} and I'm #{d.get_age}" puts "Snake: My name is #{s.get_name}, I'm #{s.get_age} & I'm #{s.get_length} cm" 




In this example, we also abandoned cats :) As always, the simplest class is higher in the hierarchy. The only difference is the super keyword. They designate variables that descendant classes should pass to the higher class. Just super will pass all variables, super() to none. Common methods go to the parent class, the descendants are left only with the initialization of variables and their own methods.



Object methods



Even a newly created, empty object already “responds” to a number of methods. puts d.methods.sort list of these methods by code: puts d.methods.sort , where d is any object. Of all, object_id should be distinguished (all Ruby objects have a unique number, which the method will output), class (will display the class to which the object belongs) and the reverse instance_of? (returns true if the object belongs to the class from the parameter, for example, puts 10.instance_of?(Fixnum) )



Can you tell if an object can respond to the message you want to send to it using the respond_to? method respond_to? . Most often it is used in the condition:



 if d.respond_to?("gav") d.gav else puts "Sorry, don't understand." end 




Proc in Ruby



A block ( do ... end or {...} ) is not an object, but it can be converted to an object of the Proc class using the lambda method. Activates the call method block from Proc . Methods can contain proc'i:



 def method proc puts 'Start of method' proc.call puts 'End of method' end say = lambda {puts 'Hello'} method say 




Epilogue



Some more useful information, a little important theory and a lot of code. It was the last drop of the kind, I promise;) Next we start to code seriously, but for now you have time to run through all the drops and collect the whole info in a heap. Comments are expected!



PS: As you can see, now all the drops in one blog. Do not forget to subscribe to it - so follow the releases even easier!



Source: https://habr.com/ru/post/49149/



All Articles