它应该在

时间:2016-08-19 01:46:30

标签: ruby method-missing

我的程序中有一个Team类,我正在尝试使用method_missing 但是当该方法不存在时,它不会运行该函数,而是给出了一个错误:“团队的未定义方法`鹰派”:类(NoMethodError)“

我的代码如下:

class Team
  attr_accessor :cust_roster, :cust_total_per, :cust_name, :cust_best_player
  @@teams = []
  def initialize(stats = {})
    @cust_roster = stats.fetch(:roster) || []
    @cust_total_per = stats.fetch(:per)
    @cust_name = stats.fetch(:name)
    @cust_best_player = stats.fetch(:best)
    @@teams << self

  end
  def method_missing(methId)
    str = methID.id2name
    Team.new(roster:[], per: 0, name: str.uppercase, best: 0)

  end



  class <<self
    def all_teams
      @@teams
    end
  end

end
hawks = Team.hawks

2 个答案:

答案 0 :(得分:4)

您的代码存在许多问题。让我们逐一介绍。

从文档中

  

method_missing(* args)private   当obj被发送一条无法处理的消息时,由Ruby调用。

此处message指的是method。在ruby中,只要您在某个对象上调用方法,您实际上send message object

为了更好地理解这一点,请在irb shell中尝试。

1+2
=> 3
1.send(:+,2)
=> 3

这里1和2是Fixnum类的对象。您可以使用1.class确认。好的,回到你的问题。因此,应在实例上调用method_missing方法。

team = Team.new
team.hawks

如果您尝试上述代码,则会收到错误消息'fetch': key not found: :roster (KeyError)

您可以通过将default value作为第二个参数传递给fetch方法来解决此问题。将您的initialize方法替换为

def initialize(stats = {})
  @cust_roster = stats.fetch(:roster, [])
  @cust_total_per = stats.fetch(:per, 0)
  @cust_name = stats.fetch(:name, "anon")
  @cust_best_player = stats.fetch(:best, "anon")
  @@teams << self

如果您执行该脚本,由于此行中存在小错误,您将获得stack level too deep (SystemStackError)

str = methID.id2name

在方法定义中,您正在接收名称为methId的参数,但在您内部尝试拨打methID。用

修复它
str = methId.id2name

如果您执行脚本,则会再次收到错误消息undefined method uppercase for "hawks":String (NoMethodError)

这是因为字符串上没有uppercase方法。您应该使用upcase方法。

Team.new(roster:[], per: 0, name: str.upcase, best: 0)

你应该好好去。

有关详情,请参阅http://apidock.com/ruby/BasicObject/method_missing

希望这有帮助!

答案 1 :(得分:0)

class Team
  attr_accessor :cust_roster, :cust_total_per, :cust_name, :cust_best_player
  @@teams = []
  def initialize(stats = {roster: [], per: 0, name: "", best: 0}) # I added the default values here. 
    @cust_roster = stats.fetch(:roster)
    @cust_total_per = stats.fetch(:per)
    @cust_name = stats.fetch(:name)
    @cust_best_player = stats.fetch(:best)
    @@teams << self

  end
  def method_missing(name, *args)
    self.cust_name = name.to_s.upcase
  end

  class << self
    def all_teams
      @@teams
    end
  end

end

team_hawks = Team.new #=> create an instance of Team class, I renamed the object to avoid confusions. 
team_hawks.hawks      #=> called method_missing which assigned the cust_name variable to "HAWKS"

team_hawks.cust_name  #=> HAWKS, so cust_name is assigned to be hawks. This is to check if the assignment worked. 

希望这就是你要找的东西。