Запрашивать информацию у пользователя и больше никогда не спрашивать

Я хочу запросить ввод данных пользователем, но я хочу сделать это только один раз (возможно, сохранить информацию в программе), то есть примерно так:

print "Enter your name (you will only need to do this once): "
name = gets.chomp

str = "Hello there #{name}" #<= As long as the user has put their name in the very first 
# time the program was run, I want them to never have to put thier name in again

Как я могу сделать это в программе Ruby?

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

Мои попытки:

def capture_user
  print 'Enter your name: '
  name = gets.chomp
end
#<= works but user has to put in name multiple times

def capture_name      
  if File.read('name.txt') == ''
    print "\e[36mEnter name to appear on email (you will only have to do this once):\e[0m "
    @esd_user = gets.chomp
    File.open('name.txt', 'w') { |s| s.puts(@esd_user) }
  else
    @esd_user = File.read('name.txt')
  end
end
#<= works but there has to be a better way to do this?

require 'tempfile'

def capture_name
  file = Tempfile.new('user')
  if File.read(file) == ''
    print "\e[36mEnter name to appear on email (you will only have to do this once):\e[0m "
    @esd_user = gets.chomp
    File.open(file, 'w') { |s| s.puts(@esd_user) }
  else
    @esd_user = File.read(file)
  end
end
#<= Also used a tempfile, this is a little bit over kill I think,
# and doesn't really help because the users can't access their Appdata

person 13aal    schedule 06.05.2016    source источник
comment
Ваш вопрос преждевременен. Что ты пробовал? Почему не сработало? Если вы еще не пробовали, почему бы и нет? Ваш пример не показывает попытки, и это то, что нам нужно увидеть. Прочтите Как спросить, включая ссылки на этой странице и минимальный воспроизводимый пример. Как бы то ни было, вы просите учебное пособие, но мы понятия не имеем, в чем заключаются ваши знания, поэтому нам придется начать с самого низа и работать дальше, что не по теме. Несколько пользователей / раз? Из разных систем? Из одной системы? Используете браузеры? Из командной строки? Очень много недостающей информации.   -  person the Tin Man    schedule 06.05.2016
comment
@theTinMan Как это?   -  person 13aal    schedule 06.05.2016
comment
Это улучшение. Является ли сохраняемая информация полезной только для человека на этой машине или она полезна для всех на всех машинах? Причина в том, что сохранение файла полезно только для человека на определенной машине. Если вам нужно поделиться информацией, вам нужно использовать общий репозиторий данных, обычно базу данных.   -  person the Tin Man    schedule 06.05.2016
comment
@theTinMan Я понимаю, что это хорошо только для пользователя на этой машине, конечным результатом является то, что это фактически станет подписью пользователя для нижних колонтитулов электронной почты.   -  person 13aal    schedule 06.05.2016
comment
Вы не можете использовать Tempfile в своих целях. Он предназначен для создания временного файла, который существует только во время выполнения скрипта. Как только скрипт завершает работу, файл удаляется. ТАК не место об этом спрашивать. Вам нужно пройти несколько руководств по файлам, получить представление о различных способах сохранения данных (плоский текстовый файл, локальная простая база данных или сериализованная структура с использованием YAML или JSON), попробовать что-то, а затем, когда у вас есть проблема с кодом задайте вопрос.   -  person the Tin Man    schedule 06.05.2016
comment
Я этого не знал. Действительно ли использование текстового файла самый простой способ сделать это?   -  person 13aal    schedule 06.05.2016
comment
meta.stackoverflow.com/questions/254572/, вероятно, будет для вас полезной страницей на данном этапе.   -  person the Tin Man    schedule 06.05.2016


Ответы (2)


Вы захотите сохранить имя пользователя в файле в локальной файловой системе. Ruby предоставляет множество способов сделать это, и в этом ответе мы рассмотрим один из них: файлы YAML.

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

Итак, как это работает? Давайте посмотрим на ваше требование, используя конфигурацию YAML:

require 'yaml'

config_filename = "config.yml"
config = {}
name = nil

if file_exists(config_filename)
  begin
    config = YAML.load_file(config_filename)
    name = config["name"]
  rescue ArgumentError => e
    puts "Unable to parse the YAML config file."
    puts "Would you like to proceed?"
    proceed = gets.chomp

    # Allow the user to type things like "N", "n", "No", "nay", "nyet", etc to abort
    if proceed.length > 0 && proceed[0].upcase == "N"
      abort "User chose not to proceed.  Aborting!"
    end
  end
end

if name.nil? || (name.strip.length == 0)
  print "Enter your name (you will only need to do this once): "
  name = gets.chomp

  # Store the name in the config (in memory)
  config["name"] = name

  # Convert config hash to a YAML config string
  yaml_string = config.to_yaml

  # Save the YAML config string to the config file
  File.open(config_filename, "w") do |out|
   YAML.dump(config, out)
  end
end

Вместо того, чтобы показать вам минимум, соответствующий вашим потребностям, этот код включает небольшую обработку ошибок и несколько простых проверок безопасности в файле конфигурации. Он вполне может быть достаточно прочным, чтобы вы могли использовать его немедленно.

Самый первый бит просто требует стандартной библиотеки YAML. Это заставляет функции YAML работать в вашей программе. Если у вас есть файл загрузчика или другой подобный распространенный механизм, просто поместите туда require 'yaml'.

После этого мы инициализируем некоторые переменные, которые используются в этом процессе. Обратите внимание, что config_filename не содержит информации о пути, поэтому он будет считан из текущего каталога. Вероятно, вы захотите сохранить файл конфигурации в обычном месте, например, в ~/.my-program-name/config.yml или C:\Documents and Settings\MyUserName\Application Data\MyProgramName\. Это можно сделать довольно легко, и есть много чего, чтобы помочь, например, этот Расположение для размещения файлов конфигурации пользователя в Windows и Расположение ini / config в linux / unix.

Затем мы проверяем, существует ли файл на самом деле, и если да, мы пытаемся прочитать из него содержимое YAML. Здесь всю тяжелую работу берет на себя метод YAML.load_file(), поэтому вам просто нужно запросить хэш конфигурации, возвращаемый для ключа, который вас интересует, в данном случае ключа "name".

Если при чтении файла YAML возникает ошибка, это указывает на то, что файл может быть поврежден, поэтому мы пытаемся с этим справиться. Файлы YAML легко редактировать вручную, но когда вы это сделаете, вы также можете легко ввести ошибку, которая приведет к сбою загрузки файла YAML. Код обработки ошибок здесь позволит пользователю прервать программу и вернуться, чтобы исправить файл YAML, чтобы он не был просто перезаписан.

После этого мы пытаемся проверить, было ли у нас правильное имя из конфигурации YAML, а если нет, мы принимаем его от пользователя. После того, как они ввели имя, мы добавляем его в хэш конфигурации, конвертируем хеш в строку в формате YAML, а затем записываем эту строку в файл конфигурации.

И это все, что нужно. Практически все, что вы можете сохранить в хэше Ruby, вы можете сохранить в файле YAML. Это очень много возможностей для хранения информации о конфигурации, и если позже вам понадобится добавить дополнительные параметры конфигурации, у вас есть универсальный контейнер, который вы можете использовать именно для этой цели.

Если вы хотите продолжить чтение по YAML, вы можете найти здесь полезную информацию:

Хотя некоторые из этих статей немного старше, они все еще очень актуальны и дадут вам отправную точку для дальнейшего чтения. Наслаждаться!

person Michael Gaskill    schedule 07.05.2016
comment
Это, наверное, один из лучших ответов, которые я когда-либо видел. - person 13aal; 07.05.2016

Если вам нужно, чтобы имя сохранялось у пользователя, запускающего сценарий несколько раз, вам нужно будет использовать какое-то хранилище данных. Как бы я ни ненавидел плоские файлы, если все, что вы храните, - это имя пользователя, я думаю, что это допустимый вариант.

if File.exist?('username.txt')
    name = File.open( 'username.txt', 'r' ) do |file|
        name = file.gets
    end
else
    print "Enter your name (you will only need to do this once): "
    name = gets.chomp

    File.open( 'username.txt', 'w' ) do |file|
        file.puts name
    end
end
str = "Hello there #{name}"
person erahm    schedule 06.05.2016
comment
Как это будет работать? Эта программа будет запускаться несколько раз в течение дня, я хочу, чтобы им приходилось вводить свое имя один раз и никогда не приходилось делать это снова. Это решение потребует от пользователя ввода своего имени при каждом запуске программы. - person 13aal; 06.05.2016
comment
Вы должны указать это в своем вопросе. Вы ничего не сказали о запуске сценария несколько раз, просто вы не хотите спрашивать их имя несколько раз - я предположил, что это происходит в каком-то цикле. Чтобы делать то, что вы хотите, вам понадобится какое-то хранилище данных. Я отредактирую свой ответ, чтобы показать вам, о чем я говорю. - person erahm; 06.05.2016
comment
Понятно, это то, что я подумал, но я не был уверен, есть ли способ сделать это в памяти Ruby. - person 13aal; 06.05.2016
comment
Каждый раз, когда ваш скрипт завершается, память стирается. Если данные будут храниться только для каждого пользователя, запускающего сценарий, и они всегда будут запускаться с одного и того же компьютера, нет необходимости настраивать фактическую базу данных. Это просто ненужные накладные расходы. - person erahm; 06.05.2016