루비의 숨겨진 특징
"...의 숨겨진 특징들" 밈을 이어서, 루비 프로그래밍 언어의 덜 알려져 있지만 유용한 특징들을 공유해 보겠습니다.
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 |