2012-01-12 2 views
1

Являются ли только основные методы Ruby применимыми с использованием синтаксиса object.functionName? Возможно ли создать собственные методы, которые можно вызывать методом точечного синтаксиса?Синтаксис синтаксиса точки против синтаксиса прокси-сервера

Для этого метода:

def namechanger (name) 

    nametochange = name 
    puts "This is the name to change: #{nametochange}" 

end 

Сначала один ниже работает, второй нет.

namechanger("Steve") 

"Steve".namechanger 

Я получаю сообщение об ошибке на "Steve".namechanger

Ошибка:

rb:21:in `<main>': private method `namechanger' called for "Steve":String (NoMethodError) 
+0

Ну, вопрос напрашивается *, что сообщение об ошибке *? А потом ** Почему это имеет смысл **? Хотя вы * можете * «открывать классы» в Ruby, это также может привести к большому загрязнению. Возможно, вы хотите следовать шаблону, например 'Person.new (« Steve »). Change_name (« Fred »)'? –

+0

Я добавил ошибку, спасибо – holaSenor

+0

Обратите внимание, что 'obj.m' * always * означает« отправить сообщение 'm' в приемник' obj', что означает, что в Ruby единственный способ сделать '" x ". m' work - включить '' x "' или родительский, например 'String', ответьте' m'. (В некоторых * других языках * возможно создание перегрузок без изменения родительских (ых) получателей или получателей.) –

ответ

3

Да, вы можете добавить методы класса Струнный для достижения желаемого эффекта; переменная «self» относится к объекту, который получает вызов метода.

class String 
    def namechanger 
    "This is the name to change: #{self}" 
    end 
end 
"Steve".namechanger # => This is the name to change: Steve 

Эта практика известна как monkey patching и должны быть тщательно используется.

+1

Примечание: * следует использовать осторожно * или (мой) * скорее всего не здесь * –

0

Что вы имеете здесь в первой форме - это метод, который принимает параметр, который сильно отличается от метода, который не принимает никаких параметров. Позвольте мне проиллюстрировать

ruby namechanger("Steve")

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

ruby "Steve".namechanger

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

+0

Итак, метод, который принимает параметры НЕ МОЖЕТ быть вызван в точечном синтаксисе, и только методы, которые не принимают аргументов CAB, вызываются с точечным синтаксисом, когда метод не принимает аргументов self используется для ссылки на объект до точки? – holaSenor

+0

«Точечный синтаксис», на который вы ссылаетесь, является всего лишь механизмом вызова метода на каком-либо объекте. Его можно использовать везде, где вы определяете метод на каком-либо объекте (классе или экземпляре класса). – jer

+0

В этом примере просто определите метод без параметров, потому что исходный метод взял одну строку, и если вы определите этот метод для самой строки, вам больше не нужно передавать ее в качестве параметра. Разумеется, вы можете определить такие методы, как 'class String; def change_to (имя); puts "Изменение # {self} до # {name}; end; end' –

0

Если вы хотите быть в состоянии назвать "Steve".namechanger, вы должны сделать namechanger это метод String класса, как это:

class String 
    def namechanger 
    puts "This is the name to change: #{self}" 
    end 
end 

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

0

Вы могли бы сделать

class String 
    def namechanger 
    puts "This is the name to change: #{self}" 
    end 
end 

Разница заключается в том, что ваш первый пример является метод, который (в основном) определено глобально, которая принимает строку и работает на нем. Однако этот код определяет метод, называемый «namechanger», который не принимает параметров и определяет его непосредственно в классе String. Таким образом, любые и все строки в вашем приложении будут иметь этот метод.

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

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

1

Вместо monkeypatching, вы можете создать подкласс и все дни, таким образом:

  1. Будьте точны, о чем вы думаете, что объект действительно есть.
  2. Gain все методы Строка

Например:

class PersonName < String 
    def namechanger 
    puts "This is the name to change: #{self}" 
    end 
end 

s = PersonName.new("Iain") 
s.namechanger 

This is the name to change: Iain 
=> nil 
+0

Я заметил, что вы передали« Iain »на новый. Но когда вы назвали namechanger на s, он по-прежнему печатался правильно. Как новый метод знал, чтобы отправить« Iain 'to def namechanger? – holaSenor

+0

Поскольку он подклассифицирует String, он действует как строка (это строка _enhanced_). Подумайте об этом, поскольку, когда вы ссылаетесь на 'self' в классе String, он вернет строку, которую она удерживает. Следовательно, Iain ". – iain

+0

На самом деле, это плохо для меня, чтобы упростить это. В любом классе' self' ссылается на себя. Если вы поместите объект String в строку типа «Это имя для изменения: ___», оно выведет строку Итак, в этом случае 'self' выведет« Iain ». – iain

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