루비의 숨겨진 특징
"...의 숨겨진 특징들" 밈을 이어서, 루비 프로그래밍 언어의 덜 알려져 있지만 유용한 특징들을 공유해 보겠습니다.
Ruby on Rails와 같은 것 없이 핵심 Ruby와의 토론을 제한하려고 합니다.
참고 항목:
(답변당 숨겨진 기능 하나만 사용하십시오.)
감사해요.
From Ruby 1.9 Proc#===는 Proc#call의 별칭입니다. 즉, Proc 개체는 다음과 같은 경우에 사용할 수 있습니다.
def multiple_of(factor)
Proc.new{|product| product.modulo(factor).zero?}
end
case number
when multiple_of(3)
puts "Multiple of 3"
when multiple_of(7)
puts "Multiple of 7"
end
피터 쿠퍼는 루비의 묘기를 잘 알고 있습니다.아마도 그의 가장 좋아하는 것은 단일 항목과 컬렉션을 모두 열거할 수 있게 하는 것입니다.(즉, 비수집 개체를 해당 개체만 포함하는 컬렉션으로 간주합니다.다음과 같이 표시됩니다.
[*items].each do |item|
# ...
end
이것이 얼마나 숨겨져 있는지는 모르겠지만, 1차원 배열로 해시를 만들어야 할 때 유용하다는 것을 알게 되었습니다.
fruit = ["apple","red","banana","yellow"]
=> ["apple", "red", "banana", "yellow"]
Hash[*fruit]
=> {"apple"=>"red", "banana"=>"yellow"}
내가 좋아하는 한 가지 요령은 스플랫을 사용하는 것입니다.* Arrays 를 설치합니다.) Arrays 이외의 개체에 확장기를 사용합니다.다음은 정규식 일치의 예입니다.
match, text, number = *"Something 981".match(/([A-z]*) ([0-9]*)/)
다른 예는 다음과 같습니다.
a, b, c = *('A'..'Z')
Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom
와우, 아무도 플립플롭 운영자에 대해 언급하지 않았습니다.
1.upto(100) do |i|
puts i if (i == 3)..(i == 15)
end
루비의 멋진 점 중 하나는 메소드를 호출하고 메소드나 클래스 정의와 같이 다른 언어가 싫어하는 곳에서 코드를 실행할 수 있다는 것입니다.
예를 들어, 실행 시간까지 알 수 없는 슈퍼 클래스(즉, 랜덤)를 가진 클래스를 만들려면 다음 작업을 수행할 수 있습니다.
class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample
end
RandomSubclass.superclass # could output one of 6 different classes.
이것은 1.9를 사용합니다.Array#sample, 방(1.8.7-only), 참 참조)Array#choice), 는 꽤 을 볼 수 .), 이 예제는 다음과 같습니다.
또 다른 멋진 예는 고정되지 않은 기본 매개 변수 값을 넣는 기능입니다(다른 언어에서 종종 요구하는 것처럼).
def do_something_at(something, at = Time.now)
# ...
end
물론 첫 번째 예제의 문제는 통화 시간이 아닌 정의 시간에 평가된다는 것입니다.따라서 슈퍼클래스가 선택되면 프로그램의 나머지 기간 동안 슈퍼클래스로 유지됩니다.
그러나 두 번째 예에서는 전화를 걸 때마다do_something_at,at입니다(well,
기능 - a 다 작 기 은 능 변 - 환Fixnum로:
>> 1234567890.to_s(2)
=> "1001001100101100000001011010010"
>> 1234567890.to_s(8)
=> "11145401322"
>> 1234567890.to_s(16)
=> "499602d2"
>> 1234567890.to_s(24)
=> "6b1230i"
>> 1234567890.to_s(36)
=> "kf12oi"
Huw Walters가 언급했듯이, 다른 방식으로 전환하는 것도 간단합니다.
>> "kf12oi".to_i(36)
=> 1234567890
기본값을 사용하는 해시!이 경우 배열입니다.
parties = Hash.new {|hash, key| hash[key] = [] }
parties["Summer party"]
# => []
parties["Summer party"] << "Joe"
parties["Other party"] << "Jane"
메타프로그래밍에 매우 유용합니다.
1.9 Proc 기능에 추가된 또 다른 재미있는 기능은 Proc#curry로, n 인수를 수락하는 Proc를 n-1을 수락하는 Proc로 바꿀 수 있습니다.위에서 언급한 Proc#=== 팁과 결합되어 있습니다.
it_is_day_of_week = lambda{ |day_of_week, date| date.wday == day_of_week }
it_is_saturday = it_is_day_of_week.curry[6]
it_is_sunday = it_is_day_of_week.curry[0]
case Time.now
when it_is_saturday
puts "Saturday!"
when it_is_sunday
puts "Sunday!"
else
puts "Not the weekend"
end
를 다운로드하고 Ruby 1.9를 합니다.make golf그러면 다음과 같은 작업을 수행할 수 있습니다.
make golf
./goruby -e 'h'
# => Hello, world!
./goruby -e 'p St'
# => StandardError
./goruby -e 'p 1.tf'
# => 1.0
./goruby19 -e 'p Fil.exp(".")'
"/home/manveru/pkgbuilds/ruby-svn/src/trunk"
읽어기를 .golf_prelude.c더 깔끔한 것들을 숨기려고요.
부울이 아닌 값의 부울 연산자입니다.
&&그리고.||
둘 다 계산된 마지막 식의 값을 반환합니다.
그것이 바로 그 이유입니다.||=변수가 정의되지 않은 경우 에서는 오른쪽에 반환된 값 식을 사용하여 변수를 업데이트합니다.이는 명시적으로 문서화된 것이 아니라 일반적인 지식입니다.
하만지그, 그▁however.&&=에 대해서는 그다지 널리 알려지지 않았습니다.
string &&= string + "suffix"
와 동등합니다.
if string
string = string + "suffix"
end
변수가 정의되지 않은 경우 진행되지 않아야 하는 파괴 작업에 매우 유용합니다.
Rails에서 제공하는 Symbol#to_proc 기능은 정말 멋집니다.
대신에
Employee.collect { |emp| emp.name }
다음과 같이 쓸 수 있습니다.
Employee.collect(&:name)
마지막 하나는 루비입니다. 문자열을 구분할 문자를 사용할 수 있습니다.다음 코드를 사용합니다.
message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"
문자열 내의 이중 따옴표를 이스케이프하지 않으려면 다른 구분 기호를 사용하면 됩니다.
contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]
구분 기호를 이스케이프하지 않아도 될 뿐만 아니라 여러 줄 문자열에 대해 다음 구분 기호를 사용할 수 있습니다.
sql = %{
SELECT strings
FROM complicated_table
WHERE complicated_condition = '1'
}
Range 개체를 무한 지연 목록으로 사용:
Inf = 1.0 / 0
(1..Inf).take(5) #=> [1, 2, 3, 4, 5]
자세한 내용은 http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/ 에서 확인할 수 있습니다.
define_method 명령을 사용하여 매우 흥미롭고 잘 알려지지 않은 메서드를 동적으로 생성합니다.예:
((0..9).each do |n|
define_method "press_#{n}" do
@number = @number.to_i * 10 + n
end
end
위의 코드는 'define_method' 명령을 사용하여 "press1" ~ "press9" 메서드를 동적으로 생성합니다. 기본적으로 동일한 코드를 포함하는 10개의 메서드를 모두 입력하는 대신, define method 명령을 사용하여 필요에 따라 즉시 이러한 메서드를 생성합니다.
모듈_함수
module_function으로 선언된 module 메서드는 module:
module M
def not!
'not!'
end
module_function :not!
end
class C
include M
def fun
not!
end
end
M.not! # => 'not!
C.new.fun # => 'not!'
C.new.not! # => NoMethodError: private method `not!' called for #<C:0x1261a00>
인수 없이 module_function을 사용하면 module_function 문 뒤에 오는 모든 module 메서드가 자동으로 module_function 자체가 됩니다.
module M
module_function
def not!
'not!'
end
def yea!
'yea!'
end
end
class C
include M
def fun
not! + ' ' + yea!
end
end
M.not! # => 'not!'
M.yea! # => 'yea!'
C.new.fun # => 'not! yea!'
다음과 같은 짧은 주입:
(1..10).inject(:+)
=> 55
경고: 이 항목은 2008년 가장 끔찍한 해킹 1위에 선정되었으므로 주의하여 사용하십시오.사실 페스트처럼 피하세요, 하지만 확실히 히든 루비입니다.
루비에 새 연산자를 추가한 슈퍼바이저
당신의 코드에서 어떤 독특한 작업을 위해 초비밀 악수 운영자를 원하는 적이 있습니까?코드 골프를 치는 것처럼?-~+~- 또는 <--->와 같은 연산자를 사용해 보십시오. 마지막 연산자는 항목의 순서를 거꾸로 하는 예제에서 사용됩니다.
저는 슈퍼레이터 프로젝트에 감탄하는 것 외에는 아무 관련이 없습니다.
파티에 늦었지만:
두 개의 동일한 길이의 배열을 사용하여 한 배열은 키를 제공하고 다른 배열은 값을 제공하는 해시로 쉽게 변환할 수 있습니다.
a = [:x, :y, :z]
b = [123, 456, 789]
Hash[a.zip(b)]
# => { :x => 123, :y => 456, :z => 789 }
Array#zip은 두 배열의 값을 "zip"하기 때문에 이 작업이 가능합니다.
a.zip(b) # => [[:x, 123], [:y, 456], [:z, 789]]
해시[]는 이러한 배열을 사용할 수 있습니다.저는 사람들이 이것을 하는 것도 보았습니다.
Hash[*a.zip(b).flatten] # unnecessary!
어느 것이 같은 결과를 낳지만, 스플랫과 플랫은 완전히 불필요합니다. 아마도 과거에는 없었을 것입니다.)
Ruby에서 해시 자동 활성화
def cnh # silly name "create nested hash"
Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
my_hash = cnh
my_hash[1][2][3] = 4
my_hash # => { 1 => { 2 => { 3 =>4 } } }
이건 정말 편리할 수도 있어요.
어레이 파괴
(a, b), c, d = [ [:a, :b ], :c, [:d1, :d2] ]
위치:
a #=> :a
b #=> :b
c #=> :c
d #=> [:d1, :d2]
이 기술을 사용하면 간단한 할당을 사용하여 모든 깊이의 중첩 배열에서 원하는 정확한 값을 얻을 수 있습니다.
Class.new()
런타임에 새 클래스를 만듭니다.인수는 파생할 클래스가 될 수 있으며, 블록은 클래스 본문입니다.또한 다음을 참조하십시오.const_set/const_get/const_defined?. 새운수등위해서기록그서래하제대로로, 업을서▁to,▁get.inspect숫자 대신 이름을 출력합니다.
매일 필요한 것은 아니지만, 필요할 때는 매우 편리합니다.
연속 번호 배열을 만듭니다.
x = [*0..5]
x를 [0, 1, 2, 3, 4, 5]로 설정합니다.
루비랜드에서 볼 수 있는 많은 마법들은 메타프로그래밍과 관련이 있습니다. 메타프로그래밍은 단순히 코드를 작성하는 것입니다.루비의.attr_accessor,attr_reader,그리고.attr_writer표준 패턴을 따라 한 줄로 두 개의 메소드를 만든다는 점에서 모두 단순한 메타프로그래밍입니다.는 Rails와 같은 관계 .has_one그리고.belongs_to.
하지만 당신만의 메타프로그래밍 트릭을 만드는 것은 매우 간단합니다.class_eval동적으로 작성된 코드를 실행합니다.
다음 예제에서는 래퍼 개체가 특정 메서드를 내부 개체로 전달할 수 있습니다.
class Wrapper
attr_accessor :internal
def self.forwards(*methods)
methods.each do |method|
define_method method do |*arguments, &block|
internal.send method, *arguments, &block
end
end
end
forwards :to_i, :length, :split
end
w = Wrapper.new
w.internal = "12 13 14"
w.to_i # => 12
w.length # => 8
w.split('1') # => ["", "2 ", "3 ", "4"]
»Wrapper.forwards하여 메드의 대기이사를에용저여장다합에 합니다.methods그것에 는 배입니다열을 합니다. 그러면 주어진 각각에 대해, 우리는define_method모든 인수와 블록을 포함하여 메시지를 함께 보내는 작업을 수행하는 새 메서드를 만듭니다.
메타프로그래밍 문제에 대한 훌륭한 자료는 럭키 스티프의 "왜 메타프로그래밍을 명확하게 보느냐"입니다.
에 반응하는 모든 것을 사용합니다.===(obj)사례 비교:
case foo
when /baz/
do_something_with_the_string_matching_baz
when 12..15
do_something_with_the_integer_between_12_and_15
when lambda { |x| x % 5 == 0 }
# only works in Ruby 1.9 or if you alias Proc#call as Proc#===
do_something_with_the_integer_that_is_a_multiple_of_5
when Bar
do_something_with_the_instance_of_Bar
when some_object
do_something_with_the_thing_that_matches_some_object
end
Module)Class),Regexp,Date기타 많은 클래스는 인스턴스 메서드를 정의합니다. ===(기타). 모두 사용할 수 있습니다.
Farrel이 알려준 것에 대해 감사합니다.Proc#call가 된Proc#===루비 1.9인치.
"루비" 바이너리(적어도 MRI)는 Perl 한 줄기를 매우 인기 있게 만든 많은 스위치를 지원합니다.
중요한 것들:
- -n "gets"만 사용하여 외부 루프를 설정합니다. 이 루프는 주어진 파일 이름 또는 STDIN과 마법처럼 작동하여 각 읽기 행을 $_로 설정합니다.
- -p -n을 하는 경우
put루프 반복의 s 루 의 에 끝 있 는 반 s - -a $F에 저장된 각 입력 라인의 .split에 대한 자동 호출
- -i 입력 파일 인플레이스 편집
- -l 입력 시 .chomp로 자동 호출
- -e 코드 일부 실행
- -c 소스 코드 확인
- -w 경고 포함
몇 가지 예:
# Print each line with its number:
ruby -ne 'print($., ": ", $_)' < /etc/irbrc
# Print each line reversed:
ruby -lne 'puts $_.reverse' < /etc/irbrc
# Print the second column from an input CSV (dumb - no balanced quote support etc):
ruby -F, -ane 'puts $F[1]' < /etc/irbrc
# Print lines that contain "eat"
ruby -ne 'puts $_ if /eat/i' < /etc/irbrc
# Same as above:
ruby -pe 'next unless /eat/i' < /etc/irbrc
# Pass-through (like cat, but with possible line-end munging):
ruby -p -e '' < /etc/irbrc
# Uppercase all input:
ruby -p -e '$_.upcase!' < /etc/irbrc
# Same as above, but actually write to the input file, and make a backup first with extension .bak - Notice that inplace edit REQUIRES input files, not an input STDIN:
ruby -i.bak -p -e '$_.upcase!' /etc/irbrc
더 유용하고 실용적인 예를 보려면 "루비 원라이너"와 "퍼럴 원라이너"를 구글에 자유롭게 검색하십시오.기본적으로 루비를 아크로와 세드의 상당히 강력한 대체물로 사용할 수 있습니다.
send() 메서드는 Ruby의 모든 클래스 또는 개체에서 사용할 수 있는 범용 메서드입니다.재정의되지 않은 경우 send()는 문자열을 수락하고 문자열이 전달되는 메서드의 이름을 호출합니다.예를 들어 사용자가 "Clr" 버튼을 클릭하면 'press_clear' 문자열이 send() 메서드로 전송되고 'press_clear' 메서드가 호출됩니다.send() 메서드는 Ruby에서 함수를 호출하는 재미있고 동적인 방법을 허용합니다.
%w(7 8 9 / 4 5 6 * 1 2 3 - 0 Clr = +).each do |btn|
button btn, :width => 46, :height => 46 do
method = case btn
when /[0-9]/: 'press_'+btn
when 'Clr': 'press_clear'
when '=': 'press_equals'
when '+': 'press_add'
when '-': 'press_sub'
when '*': 'press_times'
when '/': 'press_div'
end
number.send(method)
number_field.replace strong(number)
end
end
블로그 슈즈에서 이 기능에 대해 자세히 설명합니다. Simple-Calc 애플리케이션
클래스 또는 모듈이 실제로 필요하지 않은 것을 필요로 했다고 말하는 것을 속입니다.
$" << "something"
예를 들어 A가 B를 요구하지만 코드에는 B가 필요하지 않습니다(A는 코드를 통해서도 사용하지 않습니다).
예를 들어, Backgroundrb의 경우bdrb_test_helper requires 'test/spec'하지만 당신은 그것을 전혀 사용하지 않습니다, 그래서 당신의 코드에서:
$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
임의의 수의 매개 변수를 허용하고 모든 매개 변수를 삭제하는 메서드 정의
def hello(*)
super
puts "hello!"
end
의 위의것hello방법은 다음만 하면 됩니다.puts "hello"스크린과 콜에서super하지만 슈퍼클래스 이후로hello에서는 매개 변수도 정의하지만 실제로 매개 변수 자체를 사용할 필요는 없으므로 매개 변수 이름을 지정할 필요는 없습니다.
private unless Rails.env == 'test'
# e.g. a bundle of methods you want to test directly
Ruby의 멋지고 (경우에 따라) 유용한 해킹/기능처럼 보입니다.
언급URL : https://stackoverflow.com/questions/63998/hidden-features-of-ruby
'programing' 카테고리의 다른 글
| 설치된 종속성에서 @types 유형 제외 (0) | 2023.06.07 |
|---|---|
| 문을 사용하여 중첩됨 (0) | 2023.06.07 |
| 파이썬에서 간단한 메시지 상자를 만들려면 어떻게 해야 합니까? (0) | 2023.06.07 |
| Firebase 자동 apns 알림 (0) | 2023.06.07 |
| Ubuntu 11.04에서 R 패키지를 설치할 수 없음 (0) | 2023.06.07 |