如何避免在Ruby中使用类变量

时间:2017-06-11 11:41:48

标签: ruby class-variables

我有一段使用类变量的代码。我已经读过Ruby中通常应该避免使用类变量。

类变量为<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>io.github</groupId> <artifactId>webstore</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.8.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies> </project> @@cost

如何在不使用类变量的情况下重写以下内容?

@@kwh

2 个答案:

答案 0 :(得分:5)

@@cost的行为更像是常量(即它在运行时不会改变),所以你应该使用一个代替:

COST = 0.0946

@@kwh应该是一个实例变量,因为它仅在实例化对象中使用,因此您可以改为使用@kwh

@kwh = (watt / 1000) * hours

daily_cost = @@kwh * @@cost将成为:

daily_cost = @kwh * COST

这将避免使用类变量,但您也可以完全消除@kwh,因为您不在其他任何地方使用它。

所以,而不是:

def watt_to_kwh(hours)
  @kwh = (watt / 1000) * hours
end

你可以这样做:

def watt_to_kwh(hours)
  (watt / 1000) * hours
end

并在cost_of_energy方法中使用它:

def cost_of_energy
  puts "How many hours do you use the #{self.name} daily?"
  hours = gets.chomp.to_i
  daily_cost = watt_to_kwh(hours) * COST
  montly_cost = daily_cost * 30
  puts "Dayly cost: #{daily_cost}€"
  puts "montly_cost: #{montly_cost}€"
end

答案 1 :(得分:1)

试试这个。

class Device
  singleton_class.send(:attr_accessor, :cost_per_kwh)

  def initialize(name, watts)
    @name = name
    @watts = watts
  end

  def daily_cost(hours_per_day)
    self.class.cost_per_kwh * kwh_per_day(hours_per_day)
  end

  def monthly_cost(hours_per_day)
    30 * daily_cost(hours_per_day)
  end

  private

  def kwh_per_day(hours_per_day)
    hours_per_day * @watts / 1000
  end
end

singleton_class.send(:attr_accessor, :cost_per_kwh)为类实例变量@cost_per_kwh创建一个setter和getter。

首先,获取并保存每千瓦时的成本,这将用于计算所有感兴趣的设备的成本。

puts "Please enter the cost per kwh in $"    
Device.cost_per_kwh = gets.chomp.to_f

假设

Device.cost_per_kwh = 0.0946

计算每个感兴趣设备的成本。

puts "What is the name of the device?"
name = gets.chomp

puts "How many watts does it draw?"
watts = gets.chomp.to_f

假设

name = "chair"
watts = 20000.0

我们现在可以创建一个类实例。

device = Device.new(name, watts)
  #=> #<Device:0x007f9d530206f0 @name="chair", @watts=20000.0> 

最后,获取每天的小时数,这是在给定设备的未来成本计算中可能发生变化的唯一变量。

puts "How many hours do you use the #{name} daily?"
hours_per_day = gets.chomp.to_f

最后,假设

hours_per_day = 0.018
然后我们可以计算成本。

puts "Daily cost: $#{ device.daily_cost(hours_per_day)}"
Daily cost: $0.034056€

puts "Monthly_cost (30 days/month): $#{ 30 * device.daily_cost(hours_per_day) }"
Monthly_cost (30 days/month): $1.0216800000000001

假设情况发生变化 1 并且设备的使用增加。我们每天只需要更新时间。例如,

puts "How many hours do you use the #{name} daily?"
hours_per_day = gets.chomp.to_f

现在假设

hours_per_day = 1.5

然后

puts "Daily cost: $#{ device.daily_cost(hours_per_day)}"    
Daily cost: $2.838

puts "Monthly_cost (30 days/month): $#{ 30 * device.daily_cost(hours_per_day) }"
Monthly_cost (30 days/month): $85.14

1例如,选举新总统。