0

我在阅读图像裁剪上的导轨时遇到了这个问题,原始代码就像(删除了不相关的代码):

class User < ActiveRecord::Base
  attr_accessor :crop_x, :crop_y, :crop_w, :crop_h

  def cropping?
    !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
  end
end

正如你在这里看到的,像 :crop_x 这样的东西已经被定义和检查了四次。这是相当多余的。

因此,我想我可以定义一个符号数组,如下所示:

class User < ActiveRecord::Base
  _cropset = :crop_x, :crop_y, :crop_w, :crop_h
  _cropset.each {|attr| attr_accessor attr}

  def cropping?
    # How to properly reference to a variable from attribute..?
  end 
end 

但正如你所看到的......我被困在上面的评论部分。

我认为像上面的代码一样手动检查所有这些变量不是一个好习惯。但是我应该如何改进这段代码,以及如何使用符号引用变量?

4

2 回答 2

1

您可以*ary在参数列表中使用将数组(或可以通过to_a方法转换为数组的某些实例)转换为参数列表。

因为该def块创建了新的self绑定环境,所以您无法访问在您的实例方法(其中指的是实际实例)_cropset中的类环境(self指类)中定义的内容。您应该定义一个实例方法来返回cropset 或创建一个常量()。Usercropping?selfUser_cropsetCropSet

用于Object#send调用方法中由符号标识的cropping?方法。如sawa所示,要缩短! . &&链条,您可以使用。此外,您可以查看其他一些相关方法:Enumerable#none?

class User < ActiveRecord::Base
  CropSet = :crop_x, :crop_y, :crop_w, :crop_h
  attr_accessor *CropSet

  def cropping?
    CropSet.none?{|m| send(m).blank?}
  end 
end 
于 2013-06-30T12:34:02.350 回答
1

您可以将其作为哈希处理:

class User < ActiveRecord::Base
  attr_accessor :crop

  # somewhere in the code, `@crop` is set like `{x: foo, y: bar, w: baz, h: bang}`

  def cropping?; @crop.none?{|_, v| v.blank?} end
end

或作为数组:

class User < ActiveRecord::Base
  attr_accessor :crop

  # somewhere in the code, `@crop` is set like `[x, y, w, h]`

  def cropping?; @crop.none?(&:blank?) end
end
于 2013-06-30T10:51:53.973 回答