Ruby类方法 实例方法

ruby的类方法与实例方法

类方法也叫静态方法,通过类名来调用的方法。实例方法,必须要new一个实例出来才能用。

class Foo
  def self.bar
    puts 'class method'
  end
  
  def baz
    puts 'instance method'
  end
end

Foo.bar #class method
#Foo.baz #报错 undefined method `baz' for Foo:Class (NoMethodError)

Foo.new.baz #instance method
#Foo.new.bar #报错  undefined method `bar' for # (NoMethodError)

当中bar就是类方法,看它是如何定义的:def self.bar,self就是指向当前的类。而对于实例方法,就很简单:def baz。

像ruby这样灵活的脚本语言不多见,它提供了多种定义类方法的手段。

# Way 1
class Foo
  def self.bar
    puts 'class method'
  end
end

Foo.bar # "class method"

# Way 2
class Foo
  class << self
    def bar
      puts 'class method'
    end
  end
end

Foo.bar # "class method"

# Way 3
class Foo; end
def Foo.bar
  puts 'class method'
end

Foo.bar # "class method"

第一种与第三种方式不细说了,self的运用就相当于javascript的this。第二种有种自继承的意味。通过我们添加多个类方法时就少写几个self,非常优雅。

再看实例方法,这也有几套方案:

# Way 1
class Foo
  def baz
    puts 'instance method1'
  end
end

Foo.new.baz # "instance method1"
puts '---------------'
# Way 2
class Foo
  attr_accessor :baz
end

foo = Foo.new
foo.baz = 'instance method2'
puts foo.baz# "instance method2"

puts '---------------'

# Way 3
class Foo; end

foo = Foo.new
def foo.lazy
  puts 'instance method3'
end

foo.lazy  # "instance method3"

第一种直接定义,第二种用到attr_accessor语法糖,第三种是极晚绑定,此方法只对那一个实例有效。



#类的实例对象的方法,方法属于类所New出来的实例对象。 
p a.methods.length 
p a.class.instance_methods.length 
p A.instance_methods.length 
p a.public_methods.length 
p a.class.public_instance_methods.length 


#增加a实例的单件方法 

代码   收藏代码
  1. def a.tell  
  2.   
  3. end  
  4. p a.methods.length  
  5. p a.class.instance_methods.length  
  6. p A.instance_methods.length  
  7. p a.public_methods.length  
  8. p a.class.public_instance_methods.length  

输出:51 50 51 50 
说明:类的instance_methods包括的只有他所拥有的实例方法,并不包含单件类的方法。并且methods方法其实和Public_methods一样的,有别于private_methods 


现在说一下,method方法 

这个方法属于Method类,最常用的就是检查方法的参数个数,如下: 

  1. class A  
  2.     def self.ask1(n1,n2)  
  3.         puts "the method of class"  
  4.     end  
  5.     def ask2(n1)  
  6.         puts "the method of instance"  
  7.     end  
  8. end  
  9.   
  10. a=A.new  
  11. p a.method(:ask2).arity  
  12. p A.method(:ask1).arity  

输出:1 2 



class A
  def initialize
    @a=0;@c=3
  end
  attr_accessor :a, :c, :b
end

a = A.new

ins_vars = a.instance_variables.map{|v|v.to_s[1..-1]}
methods = a.methods.map &:to_s
ins_vars & methods #attribute

The map method takes an enumerable object and a block, and runs the block for each element, outputting each returned value from the block (the original object is unchanged unless you use map!):

[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]

Array and Range are enumerable types. map with a block returns an Array. map! mutates the original array.

Where is this helpful, and what is the difference between map! and each? Here is an example:

names = ['danil', 'edmund']

# here we map one array to another, convert each element by some rule
names.map! {|name| name.capitalize } # now names contains ['Danil', 'Edmund']

names.each { |name| puts name + ' is a programmer' } # here we just do something with each element

The output:

Danil is a programmer
Edmund is a programmer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值