如何将实例变量传入构造方法?Ruby类传参nil异常咨询
Hey there, let's work through this problem you're facing where instance variables like @my_name_generator and @my_first_name turn nil when passed into MyPerson's constructor. This is a common gotcha with Ruby variable scoping and initialization order—let's break down the likely causes and fixes.
First, Let's Clarify the Scenario (Based on Your Description)
I’m guessing your code looks something like this (feel free to adjust if I’m off):
class NameGenerator attr_accessor :surname def initialize @surname = "Doe" end end class ParentClass def initialize # You set these instance variables... @my_name_generator = NameGenerator.new @my_first_name = "Jane" # ...but when you pass them to MyPerson, they're nil inside initialize @person = MyPerson.new(@my_name_generator, @my_first_name) end end class MyPerson def initialize(name_generator, first_name) @name_generator = name_generator @first_name = first_name # Outputs nil instead of the expected values? puts "Name generator: #{@name_generator.inspect}" puts "First name: #{@first_name.inspect}" end end
Common Causes & Fixes
1. You’re Passing Variables Before They’re Initialized
This is the most frequent culprit. If you accidentally instantiate MyPerson before setting @my_name_generator or @my_first_name, those variables will be nil when passed.
Fix: Always initialize your variables first, then create the MyPerson instance:
class ParentClass def initialize # ✅ Initialize variables FIRST @my_name_generator = NameGenerator.new @my_first_name = "Jane" # ✅ Then instantiate MyPerson @person = MyPerson.new(@my_name_generator, @my_first_name) end end
2. Scoping Mismatch: Instance vs. Class Variables
If you’re trying to pass an instance variable (@var) from a class method (instead of an instance method), you’ll hit a nil issue—class methods can’t access instance-specific @ variables.
Example of the mistake:
class ParentClass @my_name_generator = NameGenerator.new # This is a CLASS instance variable, not an instance variable def self.create_person # ❌ This tries to access the class instance variable, which might not be initialized correctly MyPerson.new(@my_name_generator, "Jane") end end
Fix: Either switch to an instance method, or initialize the variable within the class method:
class ParentClass def self.create_person # ✅ Create the variable directly in the class method name_generator = NameGenerator.new MyPerson.new(name_generator, "Jane") end end
3. Typos or Incorrect Parameter Handling in MyPerson
Double-check that MyPerson’s initialize method is actually receiving the parameters correctly. A typo in the parameter name will result in nil values.
Fix: Verify parameter names match what you’re passing, and ensure you’re assigning them to instance variables properly:
class MyPerson attr_reader :name_generator, :first_name def initialize(name_generator, first_name) # ✅ No typos here—assign the incoming parameters to instance variables @name_generator = name_generator @first_name = first_name # Now this should work! puts "Full name: #{@first_name} #{@name_generator.surname}" # Outputs "Jane Doe" end end
For Ruby 3.0+, you can simplify this with parameter prefix syntax (Ruby auto-assigns the parameters to instance variables):
class MyPerson attr_reader :name_generator, :first_name def initialize(@name_generator, @first_name) # No need for manual assignment—Ruby handles it puts "Full name: #{@first_name} #{@name_generator.surname}" end end
Quick Checklist to Debug
- Did I initialize
@my_name_generatorand@my_first_namebefore passing them toMyPerson? - Am I trying to access an instance variable (
@var) from a class method? If so, adjust the scoping. - Are there typos in the parameter names in
MyPerson’sinitializemethod? - If I’m using a
NameGeneratorinstance, did I actually callnewon it to create an object (not just reference the class)?
内容的提问来源于stack exchange,提问作者rozza

