private_methods não lista private methods?


class Test

  def hello_pub
    puts "hello put"
  end
  
  private
  
  def hello_priv
    puts "hello priv"
  end
end

Test.private_methods.each do |m|
  puts m if m =~ /^h/
end

Test.methods.each do |m|
  puts m if m =~ /^h/
end

Test.public_methods.each do |m|
  puts m if m =~ /^h/
end

esquece…


class Test

  def hello_pub
    puts "hello put"
  end
  
  private
  
  def hello_priv
    puts "hello priv"
  end
end

t = Test.new

# Lista os métodos...
t.private_methods.each do |m|
  puts m if m =~ /^he/
end

# Lista os métodos...
t.public_methods.each do |m|
  puts m if m =~ /^he/
end

# Não lista...
Test.private_methods.each do |m|
  puts m if m =~ /^he/
end

# Não lista...
Test.public_methods.each do |m|
  puts m if m =~ /^he/
end

Tá aí uma diferença gritante em relação ao Java. Alguém entendeu isso? Quando vc lista os métodos de uma classe não aparece os métodos da instancia. É isso?

Sérgio, em Ruby as classes também são objetos (de verdade).

‘Test’, do seu exemplo, é na verdade uma constante que aponta para um objeto do tipo Class.

Você pode até fazer coisas do tipo:

c = Class.new
obj = c.new

Por isso Test.private_methods te dá os métodos privados do objeto apontado por Test (que é do tipo Class).

edit: digitação…

é como se em java voce estivesse listando os metodos da classe Class.

Se voce quiser listar os metodos de instancias da classe Test sem instanciar um Test, deveria fazer:

Pronto!

Os métodos daquela classe, não da equivalente à java.lang.Class.

Os métodos daquela classe, não da equivalente à java.lang.Class.[/quote]

A nao ser que voce tenha inserido “singleton methods” na classe Class de teste, ele vai listar exatamente todos os metodos de instancia da classe Class, nao é verdade? Ja que Test.class = Class. Isto é, Teste.class.methods retornara Class.methods.

Não.

>> class Bacia
>> def self.agua
>> end
\>> end
=> nil
>> Bacia.methods
=> ["inspect", [...], "agua", "clone", "method", "public_methods", "public_instance_methods",[...] ]
>> Bacia.new.methods.sort
=> ["==", "===", "=~", "__id__", "__send__", "class", "clone", "display", "dup", "eql?", "equal?", "extend", "freeze", "frozen?", "gem", "hash", "id", "inspect", "instance_eval", "instance_of?", "instance_variable_defined?", "instance_variable_get", "instance_variable_set", "instance_variables", "is_a?", "kind_of?", "method", "methods", "nil?", "object_id", "private_methods", "protected_methods", "public_methods", "require", "respond_to?", "send", "singleton_methods", "taint", "tainted?", "to_a", "to_s", "type", "untaint"]
>> self.methods.sort
=> ["==", "===", "=~", "__id__", "__send__", "bindings", "cb", "chws", "class", "clone", "conf", "context", "cws", "cwws", "display", "dup", "eql?", "equal?", "exit", "extend", "fg", "freeze", "frozen?", "gem", "hash", "help", "id", "include", "inspect", "install_alias_method", "instance_eval", "instance_of?", "instance_variable_defined?", "instance_variable_get", "instance_variable_set", "instance_variables", "irb", "irb_bindings", "irb_cb", "irb_change_binding", "irb_change_workspace", "irb_chws", "irb_context", "irb_current_working_binding", "irb_current_working_workspace", "irb_cwb", "irb_cws", "irb_cwws", "irb_exit", "irb_fg", "irb_help", "irb_jobs", "irb_kill", "irb_load", "irb_pop_binding", "irb_pop_workspace", "irb_popb", "irb_popws", "irb_print_working_binding", "irb_print_working_workspace", "irb_push_binding", "irb_push_workspace", "irb_pushb", "irb_pushws", "irb_pwb", "irb_pwws", "irb_quit", "irb_require", "irb_source", "irb_workspaces", "is_a?", "jobs", "kill", "kind_of?", "method", "methods", "nil?", "object_id", "popb", "popws", "private", "private_methods", "protected_methods", "public", "public_methods", "pushb", "pushws", "pwws", "quit", "require", "respond_to?", "send", "singleton_methods", "source", "taint", "tainted?", "to_a", "to_s", "type", "untaint", "workspaces"]

Ops, sim, aprece que estávamos falando de coisas diferentes. Se eu não modifico a classe base (class) a metaclasse do objeto vai ter os mesmos metodos que esta.

Bacia != Class, isso sim, mas voce entendeu errado o que eu quis dizer

Mas nao eh disso que eu falei Phillip, quis dizer que Bacia.class == Class, que por esse metivo que quando o saoj fazia Test.methods tava listando os metodos da classe Class, e nao os de Test (o que o Kung explicou muito mais direto que nossa enfadonha discussao)