То, что Глюки Ruby являются новичком, нужно предупредить о? [закрытый]

Неустранимая ошибка: вызов неопределенной функции XXX

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

Пример 1 - Декларация условной функции

$someCondition = false;
if ($someCondition === true) {
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

В этом случае fn() никогда не будет объявлено, потому что $someCondition не соответствует действительности.

Пример 2 - Функция в объявлении функции

function createFn() 
{
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

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

Вы также можете увидеть это для встроенной функции PHP. Попробуйте найти функцию в официальном руководстве и проверьте, к какому «расширению» (к нему принадлежит PHP-модуль), и какие версии PHP поддерживают его.

В случае отсутствующее расширение, установите это расширение и включите его в php.ini. Обратитесь к Инструкции по установке в Руководстве по PHP для расширения вашей функции. Возможно, вы также сможете включить или установить расширение с помощью диспетчера пакетов (например, apt в Debian или Ubuntu, yum в Red Hat или CentOS ) или панель управления в среде общедоступного хостинга.

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

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

В случае опечаток исправить опечатку.

Вопросы, относящиеся

106
задан 4 revs, 4 users 100% 6 April 2012 в 16:53
поделиться

21 ответ

Википедия глюки Ruby

От статьи:

  • Имена, которые начинаются с прописной буквы, рассматривают как константы, таким образом, локальные переменные должны начаться со строчной буквы.
  • символы $ и @ не указывают на переменный тип данных как в Perl, а скорее функционируют как операторы разрешения области видимости.
  • Для обозначения чисел с плавающей точкой нужно следовать с нулевой цифрой (99.0) или явным преобразованием (99.to_f). Это недостаточно для добавления точки (99.), потому что числа восприимчивы к синтаксису метода.
  • булева оценка небулевых данных строга: 0, "" и [] все оценены к [1 112]. В C выражение 0 ? 1 : 0 оценивает к [1 114] (т.е. ложь). В Ruby, однако, это уступает 1, поскольку все числа оценивают к [1 116]; [только 1 117] и false оценивают к [1 119]. Заключение к этому правилу - то, что методы Ruby условно —, например, регулярное выражение ищет — числа возврата, строки, списки или другие неложные значения на успехе, но nil при отказе (например, несоответствие). Это соглашение также используется в Smalltalk, где только специальные объекты true и false могут использоваться в булевом выражении.
  • Версиям до 1,9 недостает, символьный тип данных (сравните с C, который обеспечивает тип char для символов). Это может вызвать неожиданности при разрезании строк: "abc"[0] урожаи 97 (целое число, представляя код ASCII первого символа в строке); получить "a" использование "abc"[0,1] (подстрока длины 1) или "abc"[0].chr.
  • нотация statement until expression, в отличие от эквивалентных операторов других языков (например, do { statement } while (not(expression)); в C/C ++/...), на самом деле никогда не выполняет оператор, если выражение уже true. Это вызвано тем, что statement until expression на самом деле синтаксический сахар [более чем 1 163]

    until expression
      statement
    end
    

    , эквивалент которого в C/C++ while (not(expression)) statement; точно так же, как statement if expression, эквивалент [1 164]

    if expression
      statement
    end
    

    Однако, нотация

    begin
      statement
    end until expression
    

    в Ruby на самом деле выполнит оператор однажды, даже если выражение будет уже верно.

  • , поскольку константы являются ссылками на объекты, изменяя то, к чему относится константа, генерирует предупреждение, но изменение самого объекта не делает. Например, Greeting << " world!" if Greeting == "Hello" не генерирует ошибку или предупреждение. Это подобно [1 136] переменные в Java, но Ruby действительно также имеет функциональность, чтобы "заморозить" объект, в отличие от Java.

функции Some, которые отличаются особенно от других языков:

  • обычные операторы для условных выражений, and и or, не следуют нормальным правилам приоритета: and не связывает более трудный, чем [1 140]. Ruby также имеет операторы || и && выражения, которые работают как ожидалось.

  • def внутренний def не делает то, что мог бы ожидать Python программист:

    def a_method
        x = 7
        def print_x; puts x end
        print_x
    end
    

    Это дает ошибку [приблизительно 1 145] не быть определенным. Необходимо использовать Proc.

функции Language

  • Пропуск круглых скобок вокруг аргументов метода может привести к неожиданным результатам, если методы берут несколько параметров. Разработчики Ruby заявили, что пропуск круглых скобок на методах мультипараметра может быть запрещен в будущих версиях Ruby; ток (ноябрь 2007), интерпретатор Ruby бросает предупреждение, которое поощряет писателя не опускать (), избегать неоднозначного значения кода. Не использование () является все еще обычной практикой и может быть особенно хорошо использовать Ruby в качестве самого человекочитаемого проблемно-ориентированного языка программирования, наряду с методом, названным method_missing().
57
ответ дан 4 revs, 4 users 54% 24 November 2019 в 03:48
поделиться

Связанный с ответом monkut, Ruby to_foo методы намекают, как строгий преобразование они сделают.

Короткие как to_i, to_s говорят этому быть ленивым, и преобразовать их в целевой тип, даже если они не в состоянии быть представленными точно в том формате. Например:

"10".to_i == 10
:foo.to_s == "foo"

более длительные явные функции как to_int, to_s средний, что объект может быть исходно представлен как тот тип данных. Например, Rational класс представляет все рациональные числа, таким образом, он может быть непосредственно представлен как Fixnum (или Сверхбольшое число) целое число путем вызова to_int.

Rational(20,4).to_int == 5

, Если Вы не можете назвать более длинный метод, это означает, что объект не может быть исходно представлен в том типе.

Так в основном, при преобразовании, если Вы ленивы с именами методов, Ruby будет ленив с преобразованием.

2
ответ дан Luke 24 November 2019 в 03:48
поделиться

Я плохо знаком с рубином, и на моем первом раунде я поразил проблему относительно изменения плаваний/строк к целому числу. Я запустил с плаваний и кодировал все как f.to_int. Но когда я продвинулся и использовал тот же метод для строк, я был брошен кривая, когда он прибыл для запущения программы.

Aparently строка не имеет метод to_int , но плавает, и ints делают.

irb(main):003:0* str_val = '5.0'
=> "5.0"
irb(main):006:0> str_val.to_int
NoMethodError: undefined method `to_int' for "5.0":String
        from (irb):6
irb(main):005:0* str_val.to_i
=> 5


irb(main):007:0> float_val = 5.0
=> 5.0
irb(main):008:0> float_val.to_int
=> 5
irb(main):009:0> float_val.to_i
=> 5
irb(main):010:0>

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

2
ответ дан monkut 24 November 2019 в 03:48
поделиться

Я думаю, что всегда хорошо использовать .length на вещах..., так как размер поддерживается почти всем, и Ruby имеет динамические типы, которые можно получить действительно странные результаты, назвав .size, когда у Вас есть неправильный тип... Я очень получил бы NoMethodError: 'длина' неопределенного метода, таким образом, я обычно никогда не называю размер на объектах в Ruby.

укусил меня несколько раз.

Также помнят, что объекты имеют идентификаторы, таким образом, я пытаюсь не использовать идентификатор вызова переменных или object_id только для предотвращения беспорядка. Если мне нужен идентификатор на Объекте USERS, лучше называть его чем-то как user_id.

Просто мои два цента

3
ответ дан danmayer 24 November 2019 в 03:48
поделиться

Один это ловило меня в прошлом, то, что символ новой строки (\n) Escape sequence— среди others— не поддерживается строками в одинарных кавычках. Самой обратной косой черты оставляют. Необходимо использовать двойные кавычки для выхода для работы как ожидалось.

4
ответ дан John Topley 24 November 2019 в 03:48
поделиться
x = (true and false) # x is false

0 и '' верны, как Вы указали.

у Вас могут быть метод и модуль/класс тем же именем (который имеет смысл, потому что метод на самом деле добавляется для Возражения и таким образом имеет свое собственное пространство имен).

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

4
ответ дан 2 revs, 2 users 93% 24 November 2019 в 03:48
поделиться

Я думаю" and", и" or" намеки на Perl, который является одним из более очевидных "родителей" Ruby (самый видный другой являющийся Smalltalk). У них обоих есть намного более низкий приоритет (ниже, чем присвоение, на самом деле, который является, куда отмеченное поведение прибывает из), чем && и ||, которые являются операторами, которые необходимо использовать.

Другие вещи знать, которые не сразу очевидны:

Вы действительно не называете методы/функции, хотя это вид взглядов тот путь. Вместо этого как в Smalltalk, Вы отправляете сообщение в объект. Так method_missing действительно больше похож message_not_understood.

some_object.do_something(args)

эквивалентно [1 112]

some_object.send(:do_something, args) # note the :

, Символы очень широко используются. Это - те вещи, которые запускаются с :, и они не сразу очевидны (хорошо, они не были мне), но чем ранее Вы справляетесь с ними, тем лучше.

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

6
ответ дан Mike Woodhouse 24 November 2019 в 03:48
поделиться

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

Time.new

, Это относилось к некоторой библиотеке в месте, о котором я даже не знал.

Жаль, если я не ясен с тем, что я хочу сказать точно. Если другие столкнулись с подобными проблемами, повторно объясните.

5
ответ дан Chirantan 24 November 2019 в 03:48
поделиться

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

module Displayable
  # instance methods here
  def display
    puts name
    self.class.increment_displays
  end
  def self.included(base)
    # This module method will be called automatically
    # after this module is included in a class.
    # We want to add the class methods to the class.
    base.extend Displayable::ClassMethods
  end
  module ClassMethods
    # class methods here
    def number_of_displays
      @number_of_displays # this is a class attribute
    end
    def increment_displays
      @number_of_displays += 1
    end
    def init_displays
      @number_of_displays = 0
    end
    # this module method will be called automatically
    # after this module is extended by a class.
    # We want to perform some initialization on a
    # class attribute.
    def self.extended(base)
      base.init_displays
    end
  end
end

class Person
  include Displayable
  def name; @name; end
  def initialize(name); @name=name; end
end

puts Person.number_of_displays # => 0
john = Person.new "John"
john.display # => John
puts Person.number_of_displays # => 1
jack = Person.new "Jack"
jack.display # => Jack
puts Person.number_of_displays # => 2

Сначала, я думал, что у меня могли быть модули с обоими методами класса методов экземпляра и путем простого выполнения этого:

module Displayable
  def display
    puts name
    self.class.increment_displays
  end
  def self.number_of_displays  # WRONG!
    @number_of_displays
  end
  [...]
end

, К сожалению, метод number_of_displays никогда не будет включаться или расширяться, потому что это - "метод класса модуля". Только "методы экземпляра модуля" могут быть включены в класс (как методы экземпляра) или расширены в класс (как методы класса). Поэтому необходимо поместить методы экземпляра mixin в модуль и методы класса mixin в другой модуль (Вы обычно помещаете методы класса в подмодуль "ClassMethods"). Благодаря включал волшебный метод, можно помочь включать и методы экземпляра и методы класса во всего одном простом, "включают Визуализуемый" вызов (как показано в примере выше).

Это смешивание будет считать каждый дисплей на на класс основание. Счетчик является атрибутом класса, таким образом, каждый класс будет иметь свое собственное (Ваша программа, вероятно, перестанет работать при получении нового класса из класса Человека начиная с , счетчик @number_of_displays для производного класса никогда не будет инициализироваться). Можно хотеть заменить @number_of_displays @@ number_of_displays для создания этого глобальным счетчиком. В этом случае каждая иерархия классов будет иметь свой собственный счетчик. Если Вы хотите глобальный и уникальный счетчик, необходимо, вероятно, сделать его атрибутом модуля.

Все это было определенно не интуитивно для меня, когда я запустил с Ruby.

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

7
ответ дан 2 revs 24 November 2019 в 03:48
поделиться
  • Блоки действительно важны для понимания, они используются везде.

  • Вам не нужны круглые скобки вокруг параметров метода. Используете ли Вы их, или не ваше дело. Некоторые говорят, что необходимо всегда использовать их .

  • повышение Использования и спасение для обработки исключений, не бросают и ловят.

  • можно использовать ;, но Вы не имеете к тому, если Вы не хотите поместить несколько вещей на одну строку.

8
ответ дан 2 revs, 2 users 94% 24 November 2019 в 03:48
поделиться

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

8
ответ дан karina 24 November 2019 в 03:48
поделиться

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

class A
  @@classvar = "A1"
  @classattr = "A2"
  def self.showvars
    puts "@@classvar => "+@@classvar
    puts "@classattr => "+@classattr
  end
end

A.showvars
  # displays:
  # @@classvar => A1
  # @classattr => A2

class B < A
  @@classvar = "B1"
  @classattr = "B2"
end

B.showvars
  # displays:
  # @@classvar => B1
  # @classattr => B2

A.showvars
  # displays:
  # @@classvar => B1   #Class variables are shared in a class hierarchy!
  # @classattr => A2   #Class attributes are not
11
ответ дан MiniQuark 24 November 2019 в 03:48
поделиться

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

class A
  def hello(name="Dan")
    puts "hello #{name}"
  end
end

class B < A
  def hello(name)
    super
  end
end

B.new.hello("Bob") #=> "hello Bob"

Для фактического вызова super без аргументов необходимо сказать super().

16
ответ дан Daniel Lucraft 24 November 2019 в 03:48
поделиться
20
ответ дан 3 revs 24 November 2019 в 03:48
поделиться

Новички испытают затруднения из-за [1 121] методы равенства :

  • == b: проверки, равны ли a и b. Это является самым полезным.
  • a.eql? b: также проверки, равны ли a и b, но это иногда более строго (это могло бы проверить, что a и b имеют тот же тип, например). Это главным образом используется в Хешах.
  • a.equal? b: проверки, являются ли a и b тем же объектом (установление личности).
  • === b: используемый в случае, если операторы (я считал его как" b соответствий").

Эти примеры должны разъяснить первые 3 метода:

a = b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # true (a.object_id == b.object_id)

a = "joe"
b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # false (a.object_id != b.object_id)

a = 1
b = 1.0

a==b       # true
a.eql? b   # false (a.class != b.class)
a.equal? b # false

Примечание, что == , eql? и равный? должно всегда быть симметричным: если == b тогда b == a.

Также примечание, что == и eql? оба реализованы в объекте класса как псевдонимы к [1 131] равный? , поэтому если Вы создаете новый класс и хотите == и eql? для значения чего-то еще, чем простые идентификационные данные тогда необходимо переопределить их обоих. Например:

class Person
    attr_reader name
    def == (rhs)
      rhs.name == self.name  # compare person by their name
    end
    def eql? (rhs)
      self == rhs
    end
    # never override the equal? method!
end

метод === ведет себя по-другому. В первую очередь, это не симметрично (=== b делает не , подразумевают это b === a). Как я сказал, можно считать === b как "соответствия b". Вот несколько примеров:

# === is usually simply an alias for ==
"joe" === "joe"  # true
"joe" === "bob"  # false

# but ranges match any value they include
(1..10) === 5        # true
(1..10) === 19       # false
(1..10) === (1..10)  # false (the range does not include itself)

# arrays just match equal arrays, but they do not match included values!
[1,2,3] === [1,2,3] # true
[1,2,3] === 2       # false

# classes match their instances and instances of derived classes
String === "joe"   # true
String === 1.5     # false (1.5 is not a String)
String === String  # false (the String class is not itself a String)

случай оператор основан метод === :

case a
  when "joe": puts "1"
  when 1.0  : puts "2"
  when (1..10), (15..20): puts "3"
  else puts "4"
end

эквивалентно этому:

if "joe" === a
  puts "1"
elsif 1.0 === a
  puts "2"
elsif (1..10) === a || (15..20) === a
  puts "3"
else
  puts "4"
end

, Если Вы определяете новый класс, экземпляры которого представляют своего рода контейнер или диапазон (если это имеет что-то как , включают? или соответствие? метод), тогда Вы могли бы найти полезным переопределить метод === как это:

class Subnet
  [...]
  def include? (ip_address_or_subnet)
    [...]
  end
  def === (rhs)
    self.include? rhs
  end
end

case destination_ip
  when white_listed_subnet: puts "the ip belongs to the white-listed subnet"
  when black_listed_subnet: puts "the ip belongs to the black-listed subnet"
  [...]
end
38
ответ дан 2 revs 24 November 2019 в 03:48
поделиться

Итерация по рубиновым хешам не гарантируется в каком-либо определенном порядке. (Это не ошибка, это особенность)

Hash # sort полезен, если вам нужен определенный порядок.

Связанный вопрос: Почему массив Ruby из 1000 пар ключей и значений хешей всегда находится в определенном порядке?

1
ответ дан 24 November 2019 в 03:48
поделиться

Блоки и методы по умолчанию возвращают значение последней строки. Добавление операторов puts в конец в целях отладки может вызвать неприятные побочные эффекты

14
ответ дан 24 November 2019 в 03:48
поделиться

Следующий код удивил меня. Я думаю, что это опасная загвоздка: и легко столкнуться, и трудно отладить.

(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

Это печатает:

1
2 is even
3
4 is even
5

Но если я просто добавлю comment =anything перед блоком...

comment = nil
(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

Тогда я получаю:

1
2 is even
3 is even
4 is even
5 is even

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

Одним из решений было бы написать так:

comment = number%2==0 ? " is even" : nil

Я думаю, многие люди (включая меня) склонны писать "a = b if c" вместо "a = (c ? b : nil)", потому что это более читабельно, но очевидно, что это имеет побочные эффекты.

18
ответ дан 24 November 2019 в 03:48
поделиться
1..5.each {|x| puts x}

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

(1..5).each {|x| puts x}

, чтобы вам не казалось, что вы звоните 5.each . Я думаю, что это проблема приоритета, как и ошибка x = true и false .

0
ответ дан 24 November 2019 в 03:48
поделиться
Другие вопросы по тегам:

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