Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Есть ли способ вызвать закрытый метод класса из экземпляра в Ruby?
Кроме self.class.send :method, args..., конечно. Я хотел бы сделать довольно сложный метод доступным как на уровне класса, так и на уровне экземпляра, не дублируя код.
UPDATE :
Бранам: это было мое предположение, но я хотел убедиться, что никто другой не нашел обходного пути. Видимость в Ruby сильно отличается от таковой в Java. Вы также совершенно правы, что private не работает с методами класса, хотя это объявит частный метод класса:
class Foo
class <<self
private
def bar
puts 'bar'
end
end
end
Foo.bar
# => NoMethodError: private method 'bar' called for Foo:Class
Вот фрагмент кода, который будет сопровождать этот вопрос. Использование "private" в определении класса не относится к методам класса. Вы должны использовать "private_class_method", как в следующем примере.
class Foo
def self.private_bar
# Complex logic goes here
puts "hi"
end
private_class_method :private_bar
class <<self
private
def another_private_bar
puts "bar"
end
end
public
def instance_bar
self.class.private_bar
end
def instance_bar2
self.class.another_private_bar
end
end
f=Foo.new
f=instance_bar # NoMethodError: private method `private_bar' called for Foo:Class
f=instance_bar2 # NoMethodError: private method `another_private_bar' called for Foo:Class
Я не вижу способа обойти это. В документации говорится, что вы не можете указать получение частного метода. Кроме того, вы можете получить доступ только к закрытому методу из того же экземпляра. Класс Foo является другим объектом, чем данный экземпляр Foo.
Не считайте мой ответ окончательным. Я, конечно, не эксперт, но я хотел бы предоставить фрагмент кода, чтобы другие, кто пытается ответить, имели правильно закрытые методы класса.
Позвольте мне внести свой вклад в этот список более или менее странных решений и не-решений:
puts RUBY_VERSION # => 2.1.2
class C
class << self
private def foo
'Je suis foo'
end
end
private define_method :foo, &method(:foo)
def bar
foo
end
end
puts C.new.bar # => Je suis foo
puts C.new.foo # => NoMethodError
Если ваш метод является просто служебной функцией (то есть он не зависит ни от каких переменных экземпляра), вы можете поместить этот метод в модуль и include и extend класс, чтобы он был доступен как частный метод класса, так и частный метод экземпляра.
Именно так можно играть с "real" методами частного класса.
class Foo
def self.private_bar
# Complex logic goes here
puts "hi"
end
private_class_method :private_bar
class <<self
private
def another_private_bar
puts "bar"
end
end
public
def instance_bar
self.class.private_bar
end
def instance_bar2
self.class.another_private_bar
end
def calling_private_method
Foo.send :another_private_bar
self.class.send :private_bar
end
end
f=Foo.new
f.send :calling_private_method
# "bar"
# "hi"
Foo.send :another_private_bar
# "bar"
овации
В настоящее время вам больше не нужны вспомогательные методы. Вы можете просто встроить их в определение вашего метода. Это должно быть очень знакомо для людей Java:
class MyClass
private_class_method def self.my_private_method
puts "private class method"
end
private def my_private_method
puts "private instance method"
end
end
И нет, вы не можете вызвать частный метод класса из метода экземпляра. Однако вместо этого можно реализовать метод закрытого класса как метод открытого класса в частном вложенном классе, используя вспомогательный метод private_constant . Смотрите этот блог для получения более подробной информации.
Это, пожалуй, самый "native vanilla Ruby" способ:
class Foo
module PrivateStatic # like Java
private def foo
'foo'
end
end
extend PrivateStatic
include PrivateStatic
def self.static_public_call
"static public #{foo}"
end
def public_call
"instance public #{foo}"
end
end
Foo.static_public_call # 'static public foo'
Foo.new.public_call # 'instance public foo'
Foo.foo # NoMethodError: private method `foo' called for Foo:Class
Foo.new.foo # NoMethodError: private method `foo' called for #<Foo:0x00007fa154d13f10>
С некоторым метапрограммированием Ruby вы даже можете сделать его похожим:
class Foo
def self.foo
'foo'
end
extend PrivateStatic
private_static :foo
end
Метапрограммирование Ruby довольно мощное, поэтому вы можете технически реализовать любые правила определения области действия, которые вам могут понадобиться. Тем не менее, я все же предпочел бы ясность и минимальную неожиданность первого варианта.
Если я не ошибаюсь, разве тебе просто не нужно что-то вроде этого:
class Foo
private
def Foo.bar
# Complex logic goes here
puts "hi"
end
public
def bar
Foo.bar
end
end
Конечно, вы можете изменить второе определение, чтобы использовать свой подход self.class.send, если вы хотите избежать жесткого кодирования имени класса...