Ruby/Rails 将字符串转换为类属性

lll*_*lll 4 ruby ruby-on-rails

假设我有一个 class Article,这样:

class Article

  attr_accessor :title, :author

  def initialize(title, author)
    @title = title
    @author= author
  end

end
Run Code Online (Sandbox Code Playgroud)

此外,变量atribString包含属性名称的。我怎么能把这个字符串变成一个变量来用作吸气剂?

a = Article.new
atrib='title'
puts a.eval(atrib)     # <---- I want to do this
Run Code Online (Sandbox Code Playgroud)

扩展

假设我现在有一篇Array文章,我想按标题对它们进行排序。有没有办法使用以下方式进行紧凑版本&

col = Article[0..10]
sorted_one = col.sort_by{|a| a.try('title') }   #This works
sorted_two = col.sort_by(&:try('title'))   #This does not work
Run Code Online (Sandbox Code Playgroud)

nic*_*oga 6

您可以使用sendinstance_variable_get

a = Article.new 'Asdf', 'Coco'
a.pubic_send(:title) # (Recommended) Tries to call a public method named 'title'. Can raise NoMethodError
=> "Asdf"
# If at rails like your case:
a.try :title # Tries to call 'title' method, returns `nil` if the receiver is `nil` or it does not respond to method 'title'
=> "Asdf"
a.send(:title) # Same, but will work even if the method is private/protected
=> "Asdf"
a.instance_variable_get :@title # Looks for an instance variable, returns nil if one doesn't exist
=> "Asdf"
Run Code Online (Sandbox Code Playgroud)

对您的扩展问题的快速回答:不。&:symbolprocs的快捷方式依赖于Symbol#to_proc方法。因此,要启用该行为,您需要在 Symbol 类上重新定义该方法:

class Symbol
  def to_proc  
    ->(x) { x.instance_eval(self.to_s) }    
  end  
end

[1,2,3].map(&:"to_s.to_i * 10")
=> [10, 20, 30]
Run Code Online (Sandbox Code Playgroud)