Dopo aver sperimentato questo per un po ', io sono completamente sconcertato. Inizialmente, pensavo che Ruby avesse preso in considerazione la visibilità predefinita (pubblica, privata o protetta) quando chiami Module#define_method
. Si scopre però che sulle versioni di Ruby < = 2.0, che non è il caso:
class Foo
private
define_method :foo do
puts "Foo called!"
end
end
Foo.new.foo # Prints "Foo called!"
su Ruby 2.1 +, è ancora più confusa. Module#define_method
sembra prendere la visibilità metodo di default in considerazione:
class Foo
private
define_method :foo do
puts "Foo called!"
end
end
Foo.new.foo # NoMethodError: private method `foo' called for #<Foo:0x8cb75ac>
ma funziona solo quando si sta chiamando dal define_method
direttamente all'interno della classe. Chiamare un metodo che quindi chiama define_method
non funziona:
class Foo
def self.hello_on name
define_method name do
puts "Hello, #{name}!"
end
end
private
hello_on :foo
end
Foo.new.foo # Prints "Hello, foo!"
relative a IT Rubino! Perché?
Okay, questo chiede misure disperate ...
module DefaultMethodVisibilityAccessor
attr_reader :current_default_method_visibility
def public(*args)
@current_default_method_visibility = :public if args.empty?
super
end
def protected(*args)
@current_default_method_visibility = :protected if args.empty?
super
end
def private(*args)
@current_default_method_visibility = :private if args.empty?
super
end
end
class Module
prepend DefaultMethodVisibilityAccessor
end
module MethodDefiner
def hello_on name
define_method name do
puts "Hello, #{name}!"
end
case current_default_method_visibility
when :public
public name
when :protected
protected name
when :private
private name
end
end
end
Usage:
class Foo
extend MethodDefiner
hello_on :foo
private
hello_on :bar
end
Foo.new.foo # Prints "Hello, foo!"
Foo.new.bar # NoMethodError: private method `bar' called for #<Foo:0x8ec18fc>
Lì, fisso!
@Aguardientico Non penso che sia un duplicato. Il titolo della domanda duplicato riguarda la forzatura di un metodo come privato. Questa domanda riguarda la determinazione dell'attuale "ambito".L'unica sovrapposizione è che la domanda correlata ha una risposta dicendo che a partire da Ruby 2.1 'define_method' onora l'attuale ambito 'predefinito'. – Phrogz
L'OP chiede come rendere privato 'custom_method (: bar) ', anche OP ha detto che sta usando' define_method' quindi penso che sia duplicato perché nell'altra domanda l'OP chiede come usare 'define_method' per definire il metodo come privato – Aguardientico
Non è un duplicato. Non sto chiedendo come impostare la visibilità su un metodo che generi; Devo sapere come determinare la visibilità per un metodo chiamato all'interno di una definizione di classe. @Aguardientico –