2016-08-19 51 views
1

我在我的程序中有一个Team类,我试图使用method_missing ,但是当方法不存在时不运行该函数,它给了我一个错误:“undefined method`老鹰队的球队:类(NoMethodError)”Method_missing not running when it should

我的代码如下:

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 
+1

你是不是指'hawks = Team.new.hawks'? 'Team.hawks'试图调用不存在的类方法'hawks'。 –

+1

或者'def self.method_missing'? – ScottJ

+0

不行,因为Team.new已经是一个函数,它不会运行method_missing –

回答

4

有许多与你的代码的问题。让我们一一浏览。

从文档,

method_missing(*args) private Invoked by Ruby when obj is sent a message it cannot handle.

这里messagemethod。在Ruby中,每当你调用一个对象的方法,你实际上send荷兰国际集团一messageobject

为了更好地理解这一点,试试这个在IRB外壳。

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方法解决这个问题。与

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 

末更换你initialize方法

如果执行该脚本,你会得到一个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

希望这有助于!

+0

哇感谢很多我不能相信我错过了 –

+0

@AvyayVaradarajan,我已经更新了我的答案,以反映关于'大写'方法。看看 –

+0

感谢所有的帮助 –

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. 

希望这是你在找什么。