#!/usr/bin/env ruby
# this is the data I have
@data = {
:student => {
:id => '123477',
:first_name => 'Lazlo',
:last_name =>'Fortunatus',
:email=>'Lazlo@fortunatus.org'
},
:contact_info => {
:telephone=>'1 415 222-2222',
:address => '123 Main St',
:city =>'Beverly Hills',
:state=>'California',
:zip_code=>90210,
:social_security_number =>'111-11-1111'
}
}
class Student
# not fully implemented - this is what I need help on.
def get_id_original
# I need this to return the value @data[:student][:id]
end
def get_city_original
# I need this to return the value @data[:contact_info][:city]
end
end
s = Student.new
# this is the original method
# how can I access the @data variable here I tried @data[:student][:id] doesnt work
# I realize that data is outside of the scope of this method. However, is there any way!
s.get_id_original
# My goal is to have a singleton method that acts exactly like get_id_original,
# but get_id_original doesn't work.
def s.id
get_id_original
end
问问题
695 次
6 回答
1
首先,您的id
方法实际上必须进入课程。
你可以尝试这样的事情:
@data = { :student => { :id => '123477'} }
class Student
attr_accessor :id
def initialize(student)
self.id = student[:id]
end
end
s = Student.new(@data[:student])
puts s.id
于 2010-10-15T03:07:04.173 回答
1
可以办到!
它起初不起作用,因为@data
它是顶级对象的实例属性,所以即使Student
是从Object
该属性派生的也不在新实例中。
但是您可以传入self
,s.id
因此您唯一需要添加的是数据属性的访问器。
但是,这有点棘手,因为attr_reader
et al 是私有类方法,因此您不能直接使用它们,而且您不能(因为它是私有的)只是说self.class.attr_reader
,您必须打开Object
并执行...通过这些更改您的程序作品...
@data = { :student => { :id => '123477'} }
class Student
end
s = Student.new
def s.id o
o.data[:student][:id]
#how can I access the @data variable here I tried @data[:student][:id] doesnt work
#I realize that data is outside of the scope of this method. However, is there any way!
end
class Object
attr_reader :data
end
puts s.id self
于 2010-10-15T04:39:58.867 回答
0
您确实应该传入数据对象,以便它s
有自己的引用。
@data = { :student => { :id => '123477'} }
class Student
attr_accessor :data
def initialize(data)
@data = data
end
end
s = Student.new(@data)
# or you can use s.data = @data
def s.id
@data[:student][:id]
end
puts s.id
一个警告。对最外层范围的任何修改@data
都将反映在 中s
,因为两个@data
变量都指向内存中的同一个对象。
但是,如果您不想修改 Student 类怎么办?您可以将访问器添加到s
:
@data = { :student => { :id => '123477'} }
class Student
end
s = Student.new
class << s
attr_accessor :data
end
def s.id
@data[:student][:id]
end
s.data = @data
puts s.id
于 2012-06-01T17:57:47.607 回答
0
#!/usr/bin/ruby @data = { :student => { :id => '123477', :first_name => 'Lazlo', :last_name =>'Fortunatus', :email=>'Lazlo@fortunatus.org' }, :contact_info => { :telephone=>'1 415 222-2222', :address => '123 Main St', :city =>'Beverly Hills', :state=>'California', :zip_code=>90210, :social_security_number => '111-11-1111' } } 班级学生 定义初始化(数据) @数据 = 数据 结尾 def get_id_override @数据[:学生][:id] 结尾 def get_first_name_override @data[:student][:first_name] 结尾 def get_last_name_override @data[:student][:last_name] 结尾 def get_email_override @数据[:学生][:电子邮件] 结尾 def get_telephone_override @data[:contact_info][:telephone] 结尾 def get_city_override @data[:contact_info][:city] 结尾 def get_state_override @data[:contact_info][:state] 结尾 def get_zip_code_override @data[:contact_info][:zip_code] 结尾 def get_social_security_number_override @data[:contact_info][:social_security_number] 结尾 结尾 s = Student.new(@data) 定义 s.id get_id_override 结尾 def s.first_name get_first_name_override 结尾 def s.last_name get_last_name_override 结尾 def s.email get_email_override 结尾 def s.contact_info get_telephone_override 结尾 定义城市 获取城市覆盖 结尾 默认状态 get_state_override 结尾 def s.zipcode get_zip_code_override 结尾 def ssn get_social_security_number_override 结尾 放 s.id 放 s.first_name 放 s.last_name 发送 s.email 放 s.contact_info 把 s.city 放s.state 放 s.zipcode 放s.ssn
这是一些工作后的答案。谁有比我更好的答案,请告诉我。
于 2010-10-15T04:12:01.047 回答
0
此代码与您自己的答案等效,但有一些改进。(只有通过阅读我才意识到您要完成什么。)为了避免过于复杂,我尝试避免动态生成方法名称。
#!/usr/bin/env ruby
require 'forwardable'
@data = {
:student => {
:id => '123477',
:first_name => 'Lazlo',
:last_name =>'Fortunatus',
:email=>'Lazlo@fortunatus.org'
},
:contact_info => {
:telephone=>'1 415 222-2222',
:address => '123 Main St',
:city =>'Beverly Hills',
:state=>'California',
:zip_code=>90210,
:social_security_number =>'111-11-1111'
}
}
class ContactInfo
def initialize( data )
@data = data
end
def get_telephone_override
@data[:telephone]
end
def get_city_override
@data[:city]
end
def get_state_override
@data[:state]
end
def get_zip_code_override
@data[:zip_code]
end
def get_social_security_number_override
@data[:social_security_number]
end
end
class Student
extend Forwardable # enables delegation (see ruby-doc.org's standard library)
# delegates multiple methods to @contact_info, so they can be called on Student.
# Remember to have the leading colon.
def_delegators :@contact_info,
:get_telephone_override,
:get_city_override,
:get_state_override,
:get_zip_code_override,
:get_social_security_number_override
def initialize( data )
@data = data[:student]
# this is an example of composing objects to achieve separation of concerns.
# we use delegators so ContactInfo methods are available on the Student instance.
@contact_info = ContactInfo.new(data[:contact_info])
end
def get_id_override
@data[:id]
end
def get_first_name_override
@data[:first_name]
end
def get_last_name_override
@data[:last_name]
end
def get_email_override
@data[:email]
end
end
s = Student.new(@data)
class << s
alias_method :id, :get_id_override
alias_method :first_name, :get_first_name_override
alias_method :last_name, :get_last_name_override
alias_method :email, :get_email_override
alias_method :contact_info, :get_telephone_override
alias_method :city, :get_city_override
alias_method :state, :get_state_override
alias_method :zipcode, :get_zip_code_override
alias_method :ssn, :get_social_security_number_override
end
puts s.id
puts s.first_name
puts s.last_name
puts s.email
puts s.contact_info
puts s.city
puts s.state
puts s.zipcode
puts s.ssn
我认为如果您按照自己的意愿发布代码,您的问题会更清楚。我将建议进行编辑。
于 2012-06-01T18:35:38.557 回答
-2
您是否应该在类定义之外定义实例变量(以“@”为前缀)?
此外,您不能定义名称中带有句点的方法
于 2010-10-15T03:04:51.950 回答