Неопознанный метод `add` для класса Ruby - PullRequest
0 голосов
/ 02 ноября 2018

Это поддельное банковское приложение:

class Bank
    private def initialize
        $login = Hash.new
        puts "Welcome to HEIDI BANK!"
    end

    def add(keyVal)
        keyVal.each do |key, value|
            $login[key] = value
        end
    end

    def NewUser
        puts "What is the name of the user you would like to add?"
        user = gets.chomp
        puts "What is the password you would add?"
        pass = gets.chomp
        passsym = pass.to_sym
        $login.add(user => passsym)
    end
end

you_bank = Bank.new
you_bank.NewUser

Когда я пытаюсь запустить его, я получаю:

Welcome to HEIDI BANK!
What is the name of the user you would like to add?
12
What is the password you would add?
13

затем возникает ошибка:

in `NewUser': undefined method `add' for {}:Hash(NoMethodError)

Как бы я исправить эту ошибку? Кажется, мне придется выяснить, как позвонить Bank.add или что-то. Есть ли в хеше встроенная функция add, как в samp_array.push для массивов?

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Я уже предоставил ответ в комментариях, но я хотел сделать более длинный ответ, чтобы помочь вам. Похоже, что вы молодой программист и новичок в Ruby, поэтому я хотел бы помочь вам принять здоровые привычки. Соответственно, я реорганизовал ваш код и включил комментарии, объясняющие изменения со ссылками на ресурсы, которые вы можете прочитать, чтобы понять, почему были внесены изменения.

Это в основном второстепенные проблемы, но они важны при написании любого производственного кода или при написании кода, который другим, возможно, придется читать или использовать в будущем.

# Allows the use of STDIN.noecho which will not echo text input back to the console:
# https://stackoverflow.com/a/29334534/3784008
require 'io/console'

# Use two spaces of indentation for Ruby, not tabs and not 4 spaces:
# https://github.com/rubocop-hq/ruby-style-guide#source-code-layout
class Bank
  # The initialize method is not a private method:
  # https://stackoverflow.com/q/1567400/3784008
  def initialize
    # Use single quotes for non-interpolated strings
    # https://github.com/rubocop-hq/ruby-style-guide#strings
    puts 'Welcome to HEIDI BANK!'

    # Don't instantiate the `login` variable here; it should be lazily instantiated:
    # http://blog.jayfields.com/2007/07/ruby-lazily-initialized-attributes.html
  end

  # Use snake_case for method names
  # https://github.com/rubocop-hq/ruby-style-guide#naming
  def new_user
    puts 'What is the name of the user you would like to add?'
    user = gets.chomp

    puts 'What is the password you would add?'
    # Suppress local echo of the password as it is typed
    # https://stackoverflow.com/a/29334534/3784008
    pass = STDIN.noecho(&:gets).chomp

    # Do not call .to_sym on pass; if pass == an Integer then it will raise an exception,
    # e.g., 1.to_sym => NoMethodError: undefined method `to_sym' for 1:Integer
    { user => pass }
  end
end

Затем вы запускаете его, как делали раньше:

you_bank = Bank.new
Welcome to HEIDI BANK!
=> #<Bank:0x00007f8cc9086710>
you_bank.new_user
What is the name of the user you would like to add?
foo
What is the password you would add?
=> {"foo"=>"bar"}

Два других примечания к вашему исходному коду:

  1. Не используйте глобальные переменные (имя переменной начинается с $). Более подробное объяснение есть у этого ответа . Если вам понадобится переменная, доступная в экземпляре класса, вы должны использовать переменную экземпляра .
  2. Запись СУХОЙ код . Нет необходимости в методе add(keyVal), потому что он уже реализован в Hash к merge. Попробуйте перевести проблему, которую вы хотите решить, во что-то, что вы можете найти, в этом случае вы хотите " добавить к хэшу в ruby ​​", и первый результат Google для этого запроса будет этот ответ это подробно, как это сделать.

Надеюсь, это поможет вам.

Обновление

Ниже вы спросили "что такое ленивый экземпляр?" Краткий ответ: не назначайте переменные, пока они не потребуются. Например:

# Bad; don't do this
class Foo
  def initialize
    # This variable is instantiated when calling `Foo.new`, 
    # before it needs to be used, and so takes up memory right 
    # away vs. only once it's needed
    @variable_used_by_example_method = 'foobar'
  end

  def example_method
    puts @variable_used_by_example_method
  end
end

# Better; okay to do this
class Foo
  def initialize
  end

  def example_method
    # This variable is lazily instantiated, that is, it is not 
    # instantiated until `Foo.new.example_method` is called
    @variable_used_by_example_method = 'foobar'
    puts @variable_used_by_example_method
  end
end

В связи с вашим другим вопросом о сравнении имен пользователей и паролей с тем, что вводят пользователи, я рекомендую вам продумать проблему, а если вы все еще не уверены, то опубликуйте новый вопрос. Вопрос, который вы задали, недостаточно ясен для меня, чтобы дать вам хороший ответ. Прямо сейчас вы экспериментируете с кодом, чтобы выяснить, как все работает, и когда вы экспериментируете и изучаете, можно делать вещи, которые не вписываются в шаблоны проектирования объектно-ориентированного программирования. Но любой ответ, который я дам вам на основании того, что вы мне сказали, будет либо противоречить этим шаблонам, либо будет слишком продвинутым. (например, использовать базу данных и связанные модели в такой среде, как Rails)

Я бы не стал делать первый, потому что это был бы плохой совет, и я бы не стал делать второй, потому что вы должны лучше понимать Ruby и программировать в первую очередь. Поэтому я рекомендую вам обдумать это:

  1. Какое пошаговое объяснение вашей общей цели на простом английском языке?
  2. Как это объяснение можно описать в терминах объектно-ориентированной логики?
  3. Какой код вы можете написать для инкапсуляции этой логики?
  4. В чем разница между вашей способностью описывать логику и вашей способностью писать код для этой логики?

Тогда вы можете начать задавать конкретные вопросы, чтобы заполнить эти пробелы.

0 голосов
/ 02 ноября 2018

Вы определили add как метод экземпляра Bank, но вызываете его на $login, который является экземпляром Hash. Вызовите его для самого экземпляра Bank, который можно опустить:

def NewUser
  ...
  add(user => passsym)
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...