Program Club

일반적인 루비 관용구

proclub 2020. 11. 24. 20:26
반응형

일반적인 루비 관용구


루비에 대해 제가 좋아하는 한 가지는 대부분 매우 읽기 쉬운 언어라는 것입니다 (자체 문서화 코드에 적합).

그러나이 질문에서 영감을 얻었습니다. 루비 코드 설명||=루비에서 작동 하는 방법에 대한 설명 , 솔직히 말해서 나는 사용하지 않는 루비 관용구에 대해 생각하고있었습니다.

그래서 제 질문은 참조 된 질문의 예와 비슷합니다. 정말 능숙한 루비 프로그래머가되기 위해 알아야 할 일반적인 루비 관용구는 무엇입니까?

그건 그렇고, 참조 된 질문에서

a ||= b 

다음과 같다

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

(수정을 위해 Ian Terrell에게 감사드립니다)

편집 : 이 점이 완전히 논란의 여지가 없다는 것이 밝혀졌습니다. 올바른 확장은 실제로

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

이유는 다음 링크를 참조하십시오.

이것을 지적 해준 Jörg W Mittag에게 감사드립니다.


동일한 파일을 라이브러리 또는 스크립트로 사용하도록하는 마법의 if 절 :

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' ]

메서드 인수로 사용되는 해시의 구문 설탕

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"

블록, 프록 및 람다. 그들을 살고 숨 쉬십시오.

 # 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' ]

슬라이드 쇼 는 다음과 같이 주요 Ruby 관용구에 대해 매우 완벽합니다.

  • 두 값을 바꿉니다.

    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 서술문 에서 방법 의 전반적인 남용

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

다른 언어에서 오는 사람들에게 아마 그래서 Rubyists 자연 보이지만한다 뭔가 :의 사용 each에 찬성for .. in

some_iterable_object.each{|item| ... }

루비 1.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

다음은 다양한 소스에서 추출한 몇 가지입니다.

"if not"및 "while not"대신 "unless"및 "until"을 사용하십시오. 그러나 "else"조건이 존재할 때 "unless"를 사용하지 마십시오.

한 번에 여러 변수를 할당 할 수 있습니다.

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

그것은 미묘하게 부정확하며, 신규 사용자의 Ruby 애플리케이션에서 버그의 원인입니다.

모두 (만) 이후 nil와는 false부울 false로 평가, a ||= b실제로에 (거의 *) 동일합니다 :

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

또는 다른 Ruby 관용구로 다시 작성하려면 :

a = b unless a

(* 모든 문에는 값이 a ||= b있으므로이 값은. 와 기술적으로 동일하지 않습니다 . 그러나 문의 값에 의존하지 않으면 차이가 없습니다.)


일부 Ruby 관용구와 형식을 다루는 위키 페이지를 유지합니다.

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


나는 항상이 속기 if else 문의 정확한 구문을 잊어 버립니다. (그리고 연산자의 이름은 누구에게나 주석을 달았나요?) 루비 외부에서 널리 사용된다고 생각하지만 다른 사람이 여기에서 구문을 원하는 경우에는 다음과 같습니다.

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.size : 0


You can deepcopy with Marshaling object easily. - taken from The Ruby Programming Language

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

Note that files and I/O streams, as well as Method and Binding objects, are too dynamic to be marshaled; there would be no reliable way to restore their state.


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

is roughly:

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

I use this when b is a record which may or may not have been found, and I need to get one of its attributes.


I like how If-then-elses or case-when could be shortened because they return a value:

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

could be rewriten

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

The same could be applied to case-when:

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

Array.pack and String.unpack for working with binary files:

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

method missing magick

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]"

if you call methods that not exists in ruby objects, ruby interpreter will call method called 'method_missing' if its defined, you could user this for some tricks, like writing api wrappers, or dsl, where you don;t know all methods and parameters names


Nice question!

As I think the more intuitive & faster the code is, a better software we’re building. I will show you how I express my thoughts using Ruby in little snippets of code. Read more here

Map

We can use map method in different ways:

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

Or:

user_ids = users.map(&:id)

Sample

We can use rand method:

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

Shuffle:

[1, 2, 3].shuffle.first

And the idiomatic, simple and easiest way... sample!

[1, 2, 3].sample

Double Pipe Equals / Memoization

As you said in the description, we can use memoization:

some_variable ||= 10
puts some_variable # => 10

some_variable ||= 99
puts some_variable # => 10

Static Method / Class Method

I like to use class methods, I feel it is a really idiomatic way to create & use classes:

GetSearchResult.call(params)

Simple. Beautiful. Intuitive. What happens in the background?

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

  def initialize(params)
    @params = params
  end

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

For more info to write idiomatic Ruby code, read here

참고URL : https://stackoverflow.com/questions/613985/common-ruby-idioms

반응형