With the following code, in what way can I access @arr from Child?
class Parent
class << self
def create_singleton_variable
@arr = [1,2,3]
end
def arr
@arr
end
end
end
class Child < Parent
def get
puts self.arr
end
def self.get
puts self.arr
end
end
p "class method call #{Child.get}"
#=> ➜ ruby child.rb
#=> "class method call "
c = Child.new
p "instance call #{c.get}"
#=> ➜ ruby child.rb
#=> Traceback (most recent call last):
#=> 1: from child.rb:24:in `<main>'
#=> child.rb:15:in `get': undefined method `arr' for #<Child:0x00007fe0eb02e7d8> (NoMethodError)
I've tried many other ways as well, but don't feel the need to post them here.
edit to the question, since it appears I do need a bit more context:
I'm attempting to prepend a module into the Thor framework. I want to then access this bit of code
module ThorExtensions
module Thor
module CompletionGeneration
def self.prepended(base)
base.singleton_class.prepend(ClassMethods)
end
module ClassMethods
def completion
puts "Start Completion"
p self
p self.superclass
p self.class.superclass.subcommands
puts "End Completion"
end
end
end
end
end
results in
Start Completion
Debug
Thor
bundler: failed to load command: exe/pt (exe/pt)
NoMethodError: undefined method `subcommands' for Module:Class
/Users/tyler.thrailkill/Documents/code/backend/pt-cli/lib/thor_extensions/completion_generation.rb:13:in `completion'
/Users/tyler.thrailkill/Documents/code/backend/pt-cli/lib/debug/debug.rb:24:in `<class:Debug>'
/Users/tyler.thrailkill/Documents/code/backend/pt-cli/lib/debug/debug.rb:4:in `<top (required)>'
/Users/tyler.thrailkill/Documents/code/backend/pt-cli/lib/pt.rb:5:in `require'
/Users/tyler.thrailkill/Documents/code/backend/pt-cli/lib/pt.rb:5:in `<top (required)>'
exe/pt:13:in `require'
exe/pt:13:in `<top (required)>'
which of course is not what I want. It appears that maybe my issue is with prepending?
Edit 2
I seem to have done a terrible job of explaining my issue with prepending. Here is a fully working example showing my issue. I believe this is due to how prepending something to a class essentially creates another Class in the call stack that is called first. My hope is that I'm actually still able to access this method somehow.
class Parent
class << self
def create_singleton_variable
@arr = [1,2,3]
puts "arr is initialized #{@arr}"
end
# ... lots of code here.
def arr
puts "arr is #{@arr.inspect}"
@arr
end
end
end
module CompletionGeneration
def self.prepended(base)
base.singleton_class.prepend(ClassMethods)
end
module ClassMethods
def completion
puts "self.superclass.arr == #{self.superclass.arr.inspect}" # unable to access superclass arr
puts "self.class.superclass.arr == #{self.class.superclass.arr}" # likewise, unable to access Child's metaclass superclass
rescue Exception => e
# do nothing, this is just so you can see arr is actually initialized in the context of the Child
p e
end
end
end
Parent.prepend CompletionGeneration
class Child < Parent
create_singleton_variable
completion
arr
end
Child.new
results in the output
➜ ruby child.rb
arr is initialized [1, 2, 3]
arr is nil
self.superclass.arr == nil
#<NoMethodError: undefined method `arr' for Module:Class>
arr is [1, 2, 3]
This code should be simply copy and pastable as is.
subcommandsor the like until after they've been initialized by other class level methods.Thor, but for some reason they don't seem to be the same 'context' as the regular thor calls, resulting in empty arrays or hashes being returned. I did forget to mention that I don't really have trouble calling the methods on the object, but they're never populated, I'm guessing due to that.Thor::Basemethods for some reason, but still notThorclass methods themselves.