2016-08-19 3 views
1

У меня есть класс Team в моей программе, и я пытаюсь использовать method_missing , но вместо запуска функции, когда метод не существует, он дает мне ошибку: «undefined method` ястребов для команды: Класс (NoMethodError)»Method_missing не работает, когда он должен

Мой код выглядит следующим образом:

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.

Здесь message относится к method. В рубине, когда вы вызываете метод на объекте, вы фактически являетесь , входящим в message, на object

Чтобы лучше понять это, попробуйте это в оболочке 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 метода. Замените метод 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

Надеется, что это помогает!

+0

wow благодарит много, я не могу поверить, что я пропустил это –

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

Надеюсь, это то, что вы ищете.

Смежные вопросы