일반적인 루비 관용구
루비에 대해 제가 좋아하는 한 가지는 대부분 매우 읽기 쉬운 언어라는 것입니다 (자체 문서화 코드에 적합).
그러나이 질문에서 영감을 얻었습니다. 루비 코드 설명 과 ||=루비에서 작동 하는 방법에 대한 설명 , 솔직히 말해서 나는 사용하지 않는 루비 관용구에 대해 생각하고있었습니다.
그래서 제 질문은 참조 된 질문의 예와 비슷합니다. 정말 능숙한 루비 프로그래머가되기 위해 알아야 할 일반적인 루비 관용구는 무엇입니까?
그건 그렇고, 참조 된 질문에서
a ||= b
다음과 같다
if a == nil || a == false
a = b
end
(수정을 위해 Ian Terrell에게 감사드립니다)
편집 : 이 점이 완전히 논란의 여지가 없다는 것이 밝혀졌습니다. 올바른 확장은 실제로
(a || (a = (b)))
이유는 다음 링크를 참조하십시오.
- http://DABlog.RubyPAL.Com/2008/3/25/a-short-circuit-edge-case/
- http://DABlog.RubyPAL.Com/2008/3/26/short-circuit-post-correction/
- http://ProcNew.Com/ruby-short-circuit-edge-case-response.html
이것을 지적 해준 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
일부 참조 :
- http://cbcg.net/talks/rubyidioms/index.html
- http://www.therailsway.com/2006/12/8/idiomatic-ruby
- http://www.therailsway.com/2007/1/21/more-idiomatic-ruby
- http://www.caliban.org/ruby/rubyguide.shtml
그건 그렇고, 참조 된 질문에서
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
'Program Club' 카테고리의 다른 글
| IContainer 해결 (0) | 2020.11.24 |
|---|---|
| 어셈블리 'netstandard, Version = 2.0.0.0'에 대한 참조를 추가해야합니다. (0) | 2020.11.24 |
| select vs poll vs epoll (0) | 2020.11.24 |
| IIS 7에서 하위 도메인을 설정하는 방법 (0) | 2020.11.24 |
| JAXB 및 속성 순서 (0) | 2020.11.24 |