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であるため、最初は機能しませんでした。そのため、属性から派生したものであっても、新しいインスタンスにはありません。StudentObject

selfただし、に渡すことができるs.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

このコードは、いくつかの改善を加えて、独自の回答と同等の機能を果たします。(それを読んだだけで、あなたが達成しようとしていることがわかりました。)過度に複雑になるのを避けるために、メソッド名を動的に生成することは避けようとしました。

#!/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 に答える
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 initialize(data)
        @data = data
    終わり

    def get_id_override
        @data [:student] [:id]
    終わり

    def get_first_name_override
        @data [:student] [:first_name]
    終わり

    def get_last_name_override
        @data [:student] [:last_name]
    終わり
        def get_email_override
        @data [:student] [:email]
    終わり

    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)

def 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
終わり

def s.city
    get_city_override
終わり

def s.state
    get_state_override
終わり

def s.zipcode
    get_zip_code_override
終わり

def s.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

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 に答える
-2

クラス定義の外でインスタンス変数(接頭辞「@」)を定義する必要がありますか?

また、名前にピリオドが含まれるメソッドを定義することはできません

于 2010-10-15T03:04:51.950 に答える