2011-07-06 1 views
2

루비에 대한 C 확장을 개발 중입니다. 액세스하고있는 C 라이브러리의 함수 중 하나가 자연스럽게 루비 세계의 옵션 해시로 변환되는 옵션 구조체를받습니다.루비 C 확장에서 옵션 검사 해시 값을 확인할 때 가장 좋은 방법은 무엇입니까?

루비 쪽의 해시가 주어진 옵션에 대한 값을 정의하지 않을 때 구조체가 알려진 기본값으로 초기화됩니다. 는 C 측면에서 나는이 라인을 따라 몇 가지가 있습니다

옵션이 정의 된 값을 가지고 있지만 루비 유형이

나는 심지어 유형의 오류가 발생해야 C.

에 이해가되지 않는 경우
VALUE tmp; 

tmp = rb_hash_aref(r_hash, rb_str_new2("opt1")); 

if(TYPE(tmp) == T_STRING){ 
    strcpy (c_learn_param->opt1, StringValuePtr(tmp)); 
}else{ 
    strcpy (c_learn_param->opt1, "default value 1"); 
} 

지금 내 문제입니다 선택적 값? 과도한 것 같아요, 내가 디폴트로 돌아 가야합니까? 기본값으로 되돌아가는 문제는 { "opt1"=> 123} 사용자가 opt1을 정의하지 않은 것처럼 동일한 동작을 보게되는 것입니다. 나쁜 생각 인 것 같습니다. 루비 경고를 출력해야합니까? (사람들은 심지어 그것을 읽습니까?).

+1

TypeError에 대한 RDoc을 읽는 경우 : "예상되는 유형이 아닌 개체를 만났을 때 발생합니다." 그게 네 사건에 정확히 일어난 일이야. 디폴트 값으로 떨어지면 혼란이 야기됩니다. TypeError를 높이기위한 방법과 조건을 올바르게 문서화 한 경우에는 아무런 문제가 없습니다. – emboss

+0

그래, 나는 함수에 대한 일반적인 인수에서 (옵션이 아닌) 그렇게한다. 선택 매개 변수에 대해 동일한 작업을 수행하기에는 너무 엄격한 지 궁금합니다. 예기치 않은 값으로 끝나는 것보다 시끄럽게 실패하는 것이 낫습니다. – Camilo

답변

0

Symbol이나 String은 사실상 거의 받아 들여야합니다. 실제로는 거의 같은 의미로 사용됩니다 (따라서 ActiveSupport::HashWithIndifferentAccess).

특정 상황에 따라 tmp에서 to_s으로 전화를 걸면 그 중 어떤 것도 문자열로 변환 될 수 있습니다. 그러나 String 또는 Symbol을 받아들이는 것이 타당한 경우 TypeError를 발생시키는 것은 완벽하게 의미있는 일입니다.

입력 내용에는 최대한 유연하지만 출력물에는 엄격하게 적용하는 것이 일반적으로 좋은 아이디어이며 친숙한 라이브러리를 만듭니다.

사람들이 경고를 읽지 않는다면 일이 잘못 될 때 자신의 잘못이며, 당신은 웃고 말하고 "너에게 그렇게 말했다"라고 말할 권리가 있습니다.

+0

오 배열 키에 관한 것이 아니라 문자열과 기호 키를 모두 받아들이는 것이 좋습니다. 예를 들어 문자열이 필요하고 누군가가 객체를 전달하는 경우 문제는 해시의 값 부분에 있습니다. to_s 아이디어는 내가 기대하는 값이 문자열 일 때 끝낼 수도있는 무언가처럼 들리지만, 필요한 값이 C면에서 두 배라고 말하면 누군가가 객체를 전달하므로 그 값을 처리 할 분명한 방법이 없습니다. – Camilo

+1

@Camilo : 문제는 키가 아닌 값입니다. 이 경우 TypeError를 올리는 것은 필요한 값으로 현명하게 값을 변환 할 수없는 경우 합리적인 것처럼 보입니다. –