Home > Article > Backend Development > Compilation of Ruby metaprogramming basics study notes
Note 1:
Code contains variables, classes and methods, collectively called language construct.
# test.rb class Greeting def initialize(text) @text = text end def welcome @text end end my_obj = Greeting.new("hello") puts my_obj.class puts my_obj.class.instance_methods(false) #false means not inherited puts my_obj.instance_variables result => Greeting welcome @text
Summary:
Instance methods are inherited from the class, and instance variables exist in the object itself.
Both classes and objects are first-class values in Ruby.
Application example:
mongo API for ruby => Mongo::MongoClient # testmongo.rb require 'mongo' require 'pp' include Mongo # the members of replcation-set # test mongodb server version 2.6.0 host = "192.168.11.51" # The port of members # If the port is 27017 by default then otherport don't need to assignment otherport = "" port = otherport.length != 0 ? otherport : MongoClient::DEFAULT_PORT opts = {:pool_size => 5, :pool_timeout => 10} # Create a new connection client = MongoClient.new(host, port, opts) # puts client.class puts client.class.constants puts client.instance_variables puts client.class.instance_methods(false)
Output separately
Constant, Instance Attribute, Instance Method
Note 2: Dynamic calling
When you call a method, you are actually sending a message to an object.
class MyClass def my_method(args) args * 10 end end obj = MyClass.new puts obj.my_method(5) puts "**" puts obj.send(:my_method, 6)
Result:
50 ** 60
You can use object#send() instead of dot notation to call the MyClass#my_method() method:
obj.send(:my_method, 6)The first parameter of the
send() method is the message to be sent to the object, which can be a symbol (:symbol) or a string. The other parameters will be passed directly to the calling method.
The technology that can dynamically decide which method to call is called Dynamic Dispatch.
Note 3: The difference between symbols and strings
1. Symbols are immutable and the characters in the string can be modified.
2. Operations on symbols are faster.
3. Usually symbols are used to represent the names of things.
For example:
puts 1.send(:+, 4) => 5 String#to_sym(),String#intern() => string to symbol String#to_s(),String#id2name() => symbol to string "caoqing".to_sym() => :caoqing :caoqing.to_s() => "caoqing"
The pattern dispatch method is used in dynamic dispatch.
puts obj.class.instance_methods(true).delete_if{ |method_name| method_name !~ /^my/} result => my_method
Note 4: Dynamic Definition
Use the Module#define_method() method to define a method.
class MyClass define_method :my_method do |args| args * 3 end end obj = MyClass.new puts obj.my_method(10)
Result: <code><font face="Courier New">30</font><br>
30
# test.rb str = "My name is caoqing." def str.title? self.upcase == self end puts str.title? puts str.methods.grep(/^title?/) puts str.singleton_methods
false title? title?
Note 5:
obj.my_method Cla.class_method
Duck Typing: Whether the object can respond to methods, which can be ordinary methods or singleton methods.
def obj.method # method body end
obj can be an object reference, a constant class name or self.
Class Macro
A member of the Module#attr_*() method to define the accessor. Class macros are not keywords but methods.
Eigenclass
The singleton method cannot be found and saved in the ancestor chain according to the conventional method. obj is an object that cannot be saved and cannot exist in the class. Otherwise, all instances can share this method.
An object has a unique hidden class, called the object's eigenclass.
class << obj code end
If you want to get a reference to eigenclass, you can return self when leaving the scope:
Appendix:
The difference between class variables, instance variables, class methods and instance methods
@@
@
self(?clas,::).method : Class method
method : Instance method
# test.rb class Foo @@var = "lion" def self.method01 puts "cat" @name = "cat" @@var = "cat" puts @name end def self.method02 puts "tiger" @name = "tiger" @@var = "tiger" puts @name end def self.method03 puts "dog" @name = "dog" @@var = "dog" puts @name end def putsname puts @name puts @@var end end obj = Foo.new # obj.method01 => (NoMethodError) obj.putsname => lion Foo.method01 Foo.method02 Foo.method03 obj.putsname
Result:
lion cat cat tiger tiger dog dog dog