답변:
현재 루비로는 불가능합니다. '빈'속성을 메소드에 전달할 수 없습니다. 얻을 수있는 가장 가까운 방법은 nil을 전달하는 것입니다.
ldap_get(base_dn, filter, nil, X)
그러나 이렇게하면 범위가 LDAP :: LDAP_SCOPE_SUBTREE가 아닌 nil로 설정됩니다.
당신이 할 수있는 일은 당신의 방법 내에서 기본값을 설정하는 것입니다.
def ldap_get(base_dn, filter, scope = nil, attrs = nil)
scope ||= LDAP::LDAP_SCOPE_SUBTREE
... do something ...
end
이제 위와 같이 메서드를 호출하면 예상대로 동작합니다.
xyz||=true
. 그것이 0이면 항상 사실이라는 것입니다. 그것이 사실이라면 그것은 사실입니다.
scope ||= true
,이 작업을 수행하는 더 좋은 방법이 scope = LDAP::LDAP_SCOPE_SUBTREE if scope.nil?
. 물론 그것이 nil
잘못된 값 이라고 가정하는 것 입니다.
nil
있습니다. 어떤 사람들은 다음과 같은 표기법을 좋아할 것입니다 : ldap_get(base_dn, filter, _, X)
(참고 : 이것이 Ruby에 언제 도입되었는지 (아직) 모릅니다. 흥미로운 SO 스레드 ).
옵션 해시를 사용하는 것이 거의 항상 좋습니다.
def ldap_get(base_dn, filter, options = {})
options[:scope] ||= LDAP::LDAP_SCOPE_SUBTREE
...
end
ldap_get(base_dn, filter, :attrs => X)
options = default_options.merge(options)
시간이 지났고 버전 2 이후 Ruby는 명명 된 매개 변수를 지원합니다.
def ldap_get ( base_dn, filter, scope: "some_scope", attrs: nil )
p attrs
end
ldap_get("first_arg", "second_arg", attrs: "attr1, attr2") # => "attr1, attr2"
정의한 방식으로 할 수 없습니다 ldap_get
. 그러나 다음 ldap_get
과 같이 정의 하면 :
def ldap_get ( base_dn, filter, attrs=nil, scope=LDAP::LDAP_SCOPE_SUBTREE )
이제 다음을 수행 할 수 있습니다.
ldap_get( base_dn, filter, X )
그러나 이제 처음 두 개의 인수와 마지막 인수로 호출 할 수 없다는 문제가 있습니다 (이전과 동일한 문제이지만 이제는 마지막 인수가 다릅니다).
이에 대한 근거는 간단합니다. Ruby의 모든 인수에는 기본값이 필요하지 않으므로 지정한 방식으로 호출 할 수 없습니다. 예를 들어, 귀하의 경우 처음 두 인수에는 기본값이 없습니다.
1) 메서드를 오버로드 할 수 없습니다 ( 루비가 메서드 오버로딩을 지원하지 않는 이유는 무엇입니까? ). 새로운 메서드를 모두 작성 하지 않는 이유는 무엇 입니까?
2) 길이가 0 이상인 배열에 대해 splat 연산자 *를 사용하여 유사한 문제를 해결했습니다. 그런 다음 매개 변수를 전달할 수 있으면 배열로 해석되지만 매개 변수없이 메서드를 호출하려면 아무것도 전달할 필요가 없습니다. 참조 루비 언어 프로그래밍 페이지 187분의 186을
최근에 나는 이것에 대한 방법을 찾았습니다. 선택적 매개 변수를 사용하여 배열 클래스에 메서드를 만들어 배열의 요소를 유지하거나 버리고 싶었습니다.
이것을 시뮬레이션 한 방법은 배열을 매개 변수로 전달한 다음 해당 인덱스의 값이 nil인지 아닌지 확인하는 것입니다.
class Array
def ascii_to_text(params)
param_len = params.length
if param_len > 3 or param_len < 2 then raise "Invalid number of arguments #{param_len} for 2 || 3." end
bottom = params[0]
top = params[1]
keep = params[2]
if keep.nil? == false
if keep == 1
self.map{|x| if x >= bottom and x <= top then x = x.chr else x = x.to_s end}
else
raise "Invalid option #{keep} at argument position 3 in #{p params}, must be 1 or nil"
end
else
self.map{|x| if x >= bottom and x <= top then x = x.chr end}.compact
end
end
end
다른 매개 변수를 사용하여 클래스 메서드를 시도합니다.
array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126, 1]) # Convert all ASCII values of 32-126 to their chr value otherwise keep it the same (That's what the optional 1 is for)
산출: ["1", "2", "a", "b", "c"]
좋습니다. 계획대로 작동합니다. 이제 배열에서 세 번째 매개 변수 옵션 (1)을 전달하지 않으면 어떻게되는지 확인하고 살펴 보겠습니다.
array = [1, 2, 97, 98, 99]
p array.ascii_to_text([32, 126]) # Convert all ASCII values of 32-126 to their chr value else remove it (1 isn't a parameter option)
산출: ["a", "b", "c"]
보시다시피 배열의 세 번째 옵션이 제거되었으므로 메서드에서 다른 섹션을 시작하고 범위 (32-126)에없는 모든 ASCII 값을 제거합니다.
또는 매개 변수에서 값을 nil로 발행 할 수 있습니다. 다음 코드 블록과 유사합니다.
def ascii_to_text(top, bottom, keep = nil)
if keep.nil?
self.map{|x| if x >= bottom and x <= top then x = x.chr end}.compact
else
self.map{|x| if x >= bottom and x <= top then x = x.chr else x = x.to_s end}
end
가능합니다 :) 정의 변경
def ldap_get ( base_dn, filter, scope=LDAP::LDAP_SCOPE_SUBTREE, attrs=nil )
에
def ldap_get ( base_dn, filter, *param_array, attrs=nil )
scope = param_array.first || LDAP::LDAP_SCOPE_SUBTREE
범위는 이제 처음에 배열됩니다. 3 개의 인수를 제공하면 base_dn, filter 및 attrs가 할당되고 param_array는 []가됩니다. 4 개 이상의 인수가 있으면 param_array는 [argument1, or_more, and_more]가됩니다.
단점은 ... 불명확 한 해결책이고 정말 추합니다. 이것은 루비에서 함수 호출 도중 인수를 생략 할 수 있다는 대답입니다. :)
해야 할 또 다른 일은 범위의 기본값을 다시 작성하는 것입니다.
attrs=nil
표시 ( *param_array
) 뒤에 기본값 매개 변수 ( ) 를 사용하는 것은 구문 오류 입니다.
¶meter
하지만 Ruby 1.9에서는 "일반 매개 변수"가 뒤따를 수도 있습니다. 두 경우 모두 표시가있는 매개 변수 뒤에 기본적으로 유효한 매개 변수가 없었습니다.
명명 된 변수를 사용하면 코드를 더 읽기 쉽게 만들 수 있지만 부분 응용 프로그램으로이 작업을 수행 할 수 있습니다. John Resig는 2008 년에 JavaScript로 수행하는 방법에 대한 블로그 기사를 작성했습니다. http://ejohn.org/blog/partial-functions-in-javascript/
Function.prototype.partial = function(){
var fn = this, args = Array.prototype.slice.call(arguments);
return function(){
var arg = 0;
for ( var i = 0; i < args.length && arg < arguments.length; i++ )
if ( args[i] === undefined )
args[i] = arguments[arg++];
return fn.apply(this, args);
};
};
Ruby에서도 동일한 원칙을 적용하는 것이 가능할 것입니다 (프로토 티팔 상속 제외).
scope
사실을 당신이에 통과false
,scope ||= true
일을하지 않습니다. 그것은 다음과 동일하게 평가되고nil
설정 될 것입니다true