0
#!/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
4

6 回答 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该属性派生的也不在新实例中。

但是您可以传入selfs.id因此您唯一需要添加的是数据属性的访问器。

但是,这有点棘手,因为attr_readeret 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 回答