Где методы определяются на рубиновом верхнем уровне?

Может быть сделан в единственной команде (а не 148 из PHP):

mysql --database=dbname -B -N -e "SHOW TABLES" \
| awk '{print "SET foreign_key_checks = 0; ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; SET foreign_key_checks = 1; "}' \
| mysql --database=dbname &

необходимо любить командную строку... (Вы, возможно, должны были бы использовать --user и --password опции для mysql).

РЕДАКТИРОВАНИЕ: для предотвращения проблем внешнего ключа, добавил SET foreign_key_checks = 0; и SET foreign_key_checks = 1;

7
задан tshepang 14 July 2014 в 17:51
поделиться

1 ответ

Прежде всего, это поведение и лежащие в основе рассуждения существовали всегда; в 1.9 нет ничего нового. Техническая причина, по которой это происходит, заключается в том, что main является особенным и обрабатывается иначе, чем любой другой объект. Нет никакого причудливого объяснения: он ведет себя так, потому что он был разработан таким образом.

Хорошо, но почему? В чем причина волшебства main ? Поскольку разработчик Ruby Юкихиро Мацумото считает, что делает язык лучше , имея такое поведение:

Итак, почему методы верхнего уровня не созданы одноэлементными методами для этого объекта, вместо того, чтобы быть втянутыми как методы экземпляра в классе Object сам (и, следовательно, во все другие классы, т.е. большее загрязнение пространства имен, чем обычно предназначен). Это по-прежнему позволит методам верхнего уровня вызывать другие методы верхнего уровня. И если на объект верхнего уровня ссылались некоторые константа, такая как Main, то эти методы могут быть вызваны из любого места с Main.method (...).

Вы действительно хотите ввести «Main.print» повсюду?

Далее в обсуждении он объясняет, что он ведет себя таким образом, потому что считает «предположение естественным».

EDIT:

В ответ на ваш комментарий, ваш вопрос: нацелен на то, почему основной собственный класс, кажется, сообщает hello как метод частного экземпляра. Загвоздка в том, что ни одна из функций верхнего уровня фактически не добавляется к main , а непосредственно к Object . При работе с собственными классами семейство функций instance_methods всегда ведет себя так, как будто собственный класс все еще является исходным классом. То есть методы, определенные в классе, рассматриваются как определенные непосредственно в собственном классе. Например:

class Object
  private
  def foo
    "foo"
  end
end

self.send :foo  # => "foo"
Object.private_instance_methods(false).include? :foo  # => true
self.meta.private_instance_methods(false).include? :foo  # => true

class Bar
  private
  def bar
    "bar"
  end
end

bar = Bar.new
bar.send :bar  # => "bar"
Bar.private_instance_methods(false).include? :bar  # => true
bar.meta.private_instance_methods(false).include? :bar  # => true

Мы можем добавить метод непосредственно к собственному классу main . Сравните ваш исходный пример с этим:

def self.hello; "hello world"; end

Object.instance_methods.include? :hello  # => false
self.meta.instance_methods.include? :hello  # => true

Хорошо, но что, если мы действительно хотим знать, что данная функция определена в собственном классе, а не в исходном классе?

def foo; "foo"; end  #Remember, this defines it in Object, not on main
def self.bar; "bar"; end  #This is defined on main, not Object

foo  # => "foo"
bar  # => "bar"

self.singleton_methods.include? :foo  # => false
self.singleton_methods.include? :bar  # => true
8
ответ дан 7 December 2019 в 05:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: