一个事情就是我爱红宝石是主要它是一个非常可读的语言(这是伟大的自我说明的代码)

然而,灵感来自这样一个问题: 红宝石的代码说明 并说明如何 ||= 工作在红宝石,我是思考的红宝石语我不用,因为坦率地说,我不完全神交它们。

所以我的问题是,类似的例子,从中引用的问题,有什么共同点,但不明显,红宝石语我需要知道的是一个真正熟练的红宝石程序员?

通过这种方式,从引用的问题

a ||= b 

相当于

if a == nil || a == false
  a = b
end

(感谢伊恩*特雷尔为该修正)

编辑: 事实证明这一点并不是完全没有争议的.正确的扩大其实

(a || (a = (b))) 

看到这些联系对于为什么:

由于Jörg W米塔格指向了这一点。

有帮助吗?

解决方案

的魔力如果条款,允许同样的文件,作为图书馆或脚本:

if __FILE__ == $0
  # this library may be run as a standalone script
end

封装和解阵列:

# put the first two words in a and b and the rest in arr
a,b,*arr = *%w{a dog was following me, but then he decided to chase bob}
# this holds for method definitions to
def catall(first, *rest)
  rest.map { |word| first + word }
end
catall( 'franken', 'stein', 'berry', 'sense' ) #=> [ 'frankenstein', 'frankenberry', 'frankensense' ]

该syntatical糖哈希作方法的参数

this(:is => :the, :same => :as)
this({:is => :the, :same => :as})

散列初始化:

# this
animals = Hash.new { [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {}
# is not the same as this
animals = Hash.new { |_animals, type| _animals[type] = [] }
animals[:dogs] << :Scooby
animals[:dogs] << :Scrappy
animals[:dogs] << :DynoMutt
animals[:squirrels] << :Rocket
animals[:squirrels] << :Secret
animals #=> {:squirrels=>[:Rocket, :Secret], :dogs=>[:Scooby, :Scrappy, :DynoMutt]}

元类的语法

x = Array.new
y = Array.new
class << x
  # this acts like a class definition, but only applies to x
  def custom_method
     :pow
  end
end
x.custom_method #=> :pow
y.custom_method # raises NoMethodError

类实例的变量

class Ticket
  @remaining = 3
  def self.new
    if @remaining > 0
      @remaining -= 1
      super
    else
      "IOU"
    end
  end
end
Ticket.new #=> Ticket
Ticket.new #=> Ticket
Ticket.new #=> Ticket
Ticket.new #=> "IOU"

块、处和lambda.生活和呼吸。

 # know how to pack them into an object
 block = lambda { |e| puts e }
 # unpack them for a method
 %w{ and then what? }.each(&block)
 # create them as needed
 %w{ I saw a ghost! }.each { |w| puts w.upcase }
 # and from the method side, how to call them
 def ok
   yield :ok
 end
 # or pack them into a block to give to someone else
 def ok_dokey_ok(&block)
    ok(&block)
    block[:dokey] # same as block.call(:dokey)
    ok(&block)
 end
 # know where the parentheses go when a method takes arguments and a block.
 %w{ a bunch of words }.inject(0) { |size,w| size + 1 } #=> 4
 pusher = lambda { |array, word| array.unshift(word) }
 %w{ eat more fish }.inject([], &pusher) #=> ['fish', 'more', 'eat' ]

其他提示

幻灯片 是相当完整的红宝石主要习惯用语,如:

  • 交换两个价值:

    x, y = y, x

  • 参数,如果没有指定,采取一些默认值

    def somemethod(x, y=nil)

  • 批了无关的参数进一阵

    def substitute(re, str, *rest)

等等...

一些更多的成语:

使用的 %w, %r%(

%w{ An array of strings %}
%r{ ^http:// }
%{ I don't care if the string has 'single' or "double" strings }

类型的比较情况下的发言

def something(x)
  case x
    when Array
      # Do something with array
    when String
      # Do something with string
    else
      # You should really teach your objects how to 'quack', don't you?
  end
end

...和整体的滥用 === 方法在情况下的发言

case x
  when 'something concrete' then ...
  when SomeClass then ...
  when /matches this/ then ...
  when (10...20) then ...
  when some_condition >= some_value then ...
  else ...
end

东西,应该是自然的到ruby爱好者也,但是也许不那么为人来自其他语言:使用 each 在赞成 for .. in

some_iterable_object.each{|item| ... }

在Ruby1.9+、轨道,或通过修修补补的符号#to_proc方法, 是变得越来越受欢迎的成语:

strings.map(&:upcase)

有条件的方法/恒定义

SOME_CONSTANT = "value" unless defined?(SOME_CONSTANT)

查询方法和破坏性的(爆炸)的方法

def is_awesome?
  # Return some state of the object, usually a boolean
end

def make_awesome!
  # Modify the state of the object
end

隐示图标参数

[[1, 2], [3, 4], [5, 6]].each{ |first, second| puts "(#{first}, #{second})" }

我喜欢这样的:

str = "Something evil this way comes!"
regexp = /(\w[aeiou])/

str[regexp, 1] # <- This

这是(大约)相当于:

str_match = str.match(regexp)
str_match[1] unless str_match.nil?

或至少,是我用来替代这样的区块。

我建议读通过代码的流行和设计良好的插件或是从人们欣赏和尊重。

一些例子,我已经运行为:

if params[:controller] == 'discussions' or params[:controller] == 'account'
  # do something here
end

对应

if ['account', 'discussions'].include? params[:controller]
  # do something here
end

其后将是重要

if ALLOWED_CONTROLLERS.include? params[:controller]
  # do something here
end

这里有一个少数,挑选出来自各种来源:

使用"除非"和"直到"而不是"如果不是"和",而不是"。尽量不要使用"除非"当一个"别的"情况存在,虽然。

记住,你可以分配多个变量:

a,b,c = 1,2,3

甚至换变量没有一个温度:

a,b = b,a

使用移动条件适当时,例如

do_something_interesting unless want_to_be_bored?

要知道的一个常用但并不立即显而易见的(至少对我来说)的方式的定义类方法:

class Animal
  class<<self
    def class_method
      puts "call me using Animal.class_method"
    end
  end
end

一些参考文献:

通过这种方式,从引用的 的问题

a ||= b 

相当于

if a == nil   
  a = b 
end

这是微妙地不正确的,并且是源的错误,在新人的红宝石的应用。

由于这两个(并且只有) nilfalse 评估boolean false, a ||= b 实际上是(几乎*)相当于:

if a == nil || a == false
  a = b
end

或者,要改写这与另一个的红宝石成语:

a = b unless a

(*由于每个发言都有一个价值,这些都不是技术上说相当于 a ||= b.但如果你不依赖的价值的发言,你不会看到差别。)

我保持一wiki网页,涵盖了一些红宝石成语和格式化:

https://github.com/tokland/tokland/wiki/RubyIdioms

我总是忘了确切的语法的这一速记,如果其他发言(及姓名的操作者。评论意见的人?) 我认为这是广泛使用之外的红宝石,但在情况下别人的想法那就是:

refactor < 3 ? puts("No need to refactor YET") : puts("You need to refactor this into a  method")

膨胀

if refactor < 3
  puts("No need to refactor YET")
else
  puts("You need to refactor this into a  method")
end

更新

所谓的三操作员:

回myvar:?myvar:.尺寸:0

你可以deepcopy与封送对象,很容易。-取自红宝石编程语言

def deepcopy(o)
  Marshal.load(Marshal.dump(o))
end

注意,文件和I/O流, 以及方法和结合对象, 太动态是封送;还有 将没有可靠的方式恢复 他们的状态。

a = (b && b.attribute) || "default"

大致为:

if ( ! b.nil? && ! b == false) && ( ! b.attribute.nil? && ! b.attribute.false) a = b
else a = "default"

我用这个时候b是一个记录其可能或不可能已经找到了,我需要得到一个其属性。

我喜欢,如果-然后-别人或情况时,可以缩短,因为他们返回的值:

if test>0
  result = "positive"
elsif test==0
  result = "zero"
else
  result = "negative"
end

可能是rewriten

result = if test>0
  "positive"
elsif test==0
  "zero"
else
  "negative"
end

同样可以应用情况时:

result = case test
when test>0 ; "positive"
when test==0 ; "zero"
else "negative"
end

阵列。包和串。解开使用的二进制文件:

# extracts four binary sint32s to four Integers in an Array
data.unpack("iiii") 

方法缺失的魔法

class Dummy  
  def method_missing(m, *args, &block)  
    "You just called method with name #{m} and arguments- #{args}"  
  end  
end

Dummy.new.anything(10, 20)
=> "You just called method with name anything and arguments- [10, 20]"

如果你打电话的方法,不存在红宝石的对象,红宝石口译员将调的方法称为'method_missing'如果其定义,可以用这些技巧,就像写api包装,或dsl,在那里你不知道所有的方法和参数的名字

好的问题!

因为我认为更为直观和更快速的代码是一个更好的软件,我们正在建设。我会告诉你我是如何表达我的想法使用红宝石在小段代码。 读取更多的在这里

地图

我们可以利用图的方法不同的方式:

user_ids = users.map { |user| user.id }

或者:

user_ids = users.map(&:id)

样本

我们可以使用rand方法:

[1, 2, 3][rand(3)]

随机:

[1, 2, 3].shuffle.first

和习惯用语、简单和容易的办法...样品!

[1, 2, 3].sample

双管Equals/性记忆化

正如你所说的在说明,我们可以使用性记忆化:

some_variable ||= 10
puts some_variable # => 10

some_variable ||= 99
puts some_variable # => 10

静态的方法/类方法

我喜欢用类方法,我觉得它是一个真正地惯用的方式来创建和使用类:

GetSearchResult.call(params)

简单的。美丽的。直观。发生什么背景?

class GetSearchResult
  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # ... your code here ...
  end
end

更多的信息编写惯用红宝石码阅读 在这里,

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top