Ruby on rails 干掉这个ruby代码的最好方法是什么?
我想擦干这段代码。在rails中使用before_action方法是最好的解决方案吗Ruby on rails 干掉这个ruby代码的最好方法是什么?,ruby-on-rails,ruby,dry,Ruby On Rails,Ruby,Dry,我想擦干这段代码。在rails中使用before_action方法是最好的解决方案吗 class Direction attr_accessor :dir def initialize(dir) @dir = dir end DIRECTIONS = %w[N E S W] def turn_left d = DIRECTIONS.find_index(dir) @dir = DIRECTIONS.rotate!(d-1
class Direction
attr_accessor :dir
def initialize(dir)
@dir = dir
end
DIRECTIONS = %w[N E S W]
def turn_left
d = DIRECTIONS.find_index(dir)
@dir = DIRECTIONS.rotate!(d-1).first
end
def turn_right
d = DIRECTIONS.find_index(dir)
@dir = DIRECTIONS.rotate!(d+1).first
end
end
你可以:
常数以避免修改冻结
- 如果常量未在
类之外使用,请更改其可见性方向
- 如果只在类本身中使用
,请更改其可见性dir
- 创建一个
hash,它定义了返回下一个方向的方向和操作OPERATIONS
- 迭代
键,动态定义方法操作
和左转
右转
- 定义一个
方法,该方法使用direction\u index
返回dir
中的索引DIRECTIONS
- 定义一个转弯方法,该方法接收一个
参数:操作
- 使用
可以从operation
获取操作,该操作告诉您如何旋转(正旋转或负旋转)OPERATIONS
- 将方法
或-
应用于+
方向索引的结果,可以得到要旋转的参数
- 然后调用
上的DIRECTIONS
,并获取第一个元素rotate
- 使用
class DirectionMap
def initialize(*list)
# Create a Hash mapping table with left and right directions
# pre-computed. This uses modulo to "wrap" the array around.
@directions = list.map.with_index do |dir, i|
[ dir, [ list[(i - 1) % list.length], list[(i + 1) % list.length] ] ]
end.to_h
end
# These methods use dig to avoid blowing up on an invalid direction,
# instead just returning nil for garbage input.
def left(dir)
@directions.dig(dir, 0)
end
def right(dir)
@directions.dig(dir, 1)
end
end
您现在可以在其中导航任意指南针映射:
map = DirectionMap.new(*%w[ N E S W ])
map.left('N') # => 'W'
map.left(map.left('N')) # => 'S'
map.right('N') # => 'E'
map.right(map.left('N')) # => 'N'
因此,您也可以执行
%w[N NE E SE S SW w NW]
。我建议使用哈希,主要是为了可读性
class Direction
NEXT_LEFT = { 'N'=>'W', 'W'=>'S', 'S'=>'E', 'E'=>'N' }
NEXT_RIGHT = NEXT_LEFT.invert
attr_reader :dir
def initialize(dir)
@dir = dir
end
def turn_left
turn(NEXT_LEFT)
end
def turn_right
turn(NEXT_RIGHT)
end
private
def turn(nxt)
@dir = nxt[@dir]
end
end
注:
有很多很好的答案,但一个简单的直接解决方案是将两种方法中常见的部分分解成一个turn方法,然后传入
1
或-1
class Direction
attr_accessor :dir
def initialize(dir)
@dir = dir
end
DIRECTIONS = %w[N E S W]
def turn(delta_d)
d = DIRECTIONS.find_index(dir)
@dir = DIRECTIONS.rotate!(d + delta_d).first
end
def turn_left
turn(-1)
end
def turn_right
turn(1)
end
end
我认为,您可以避免每次打开时创建新阵列的所有工作(通过调用
rotate
)。只需将当前方向存储为其字母在数组中的索引。旋转只是索引上的模运算(注意在Ruby中为-1%4==3)。当需要方向的字母时,只需使用索引从数组中获取它
类方向
方向=%w[N东S西]。冻结
def初始化(dir)
self.dir=dir
结束
#迪尔盖特
def目录
方向[@dir_索引]
结束
#定向器
def dir=(dir)
@dir\u index=方向索引(dir)
结束
#转向逻辑
def转弯(三角洲)
@dir_index=(@dir_index+delta)%DIRECTIONS.size
迪尔
结束
左转
转弯(-1)
结束
右转
转弯(1)
结束
结束
p方向。新('N')。左转#=>“W”
p方向。新建('E')。左转#=>“N”
p方向。新建('S')。左转#=>“E”
p方向。新建('W')。向左拐#=>“S”
p方向。新('N')。右转#=>“E”
p方向。新建('E')。右转#=>“S”
p方向。新('S')。右转#=>“W”
p方向。新('W')。右转#=>“N”
一些控制器代码会很有用。将状态与方向概念分开可能更有意义。这种方法将两件事混为一谈,即基本方向的定义和方向状态的存储。您可以使用dir
而不是@dir
来简化方法,因为您有attr\u访问器:dir
“是否可以像在rails中那样在ruby中实现?”?你知道Rails是Ruby代码,对吧?所以,当然有可能。调用rotate代码>修改您的方向
常量所指的数组。不要这样做-常量不应该是偶然的。好的和简单的,使它非常自我记录!我会给你的代码的答案,因为它是尽可能干燥。我可能还会添加一个掉头方法。:-)
d = Direction.new('N')
d.dir
#=> "N"
d.turn_left
#=> "W"
d.turn_left
#=> "S"
d.turn_right
#=> "W"
NEXT_RIGHT
#=> {"W"=>"N", "S"=>"W", "E"=>"S", "N"=>"E"}
class Direction
attr_accessor :dir
def initialize(dir)
@dir = dir
end
DIRECTIONS = %w[N E S W]
def turn(delta_d)
d = DIRECTIONS.find_index(dir)
@dir = DIRECTIONS.rotate!(d + delta_d).first
end
def turn_left
turn(-1)
end
def turn_right
turn(1)
end
end