반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함

FAQ Wednesday #4 - Corona SDK -

2012. 5. 9. 16:51 | Posted by 솔웅


FAQ Wednesday #4

수요일입니다. FAQ 시간이죠. 아래에 자주 질문되는 5가지 문답이 있습니다. (FAQ)

Question 1

함수를 만들 때 가끔 함수 이름이 nil 이라는 에러 메세지를 가끔 보게 됩니다. 그것을 바로잡기 위해 이렇게 저렇게 코딩을 바꾸는데요. 함수 생성과 관련해서 올바른 방법은 뭔가요?

Answer

일반적으로 Lua 는 변수가 Local 일 경우에 변수에 forward references 를 요구합니다. 이 의미는 변수가 사용될 수 있게 하기 전에 변수가 정의 될 필요가 있습니다. 아래 예제를 보세요.


local function getTax( num )
    return num * 0.0825
end


print( getTax( 99.95 ) )

위의 코드는 정상적으로 동작할 겁니다. 왜냐하면 getTax가 먼저 정의 됐기 때문이죠.

print( getTax( 99.95 ) )

local function getTax( num )

    return num * 0.0825
end


The above doesn’t work because getTax is unknown and returns with a “nil” error. If you always define your variables or functions first (before being called), you won’t have any problems, but sometimes you can’t avoid it. Here is how you can fix 

위와 같이 하면 에러가 날겁니다. 왜냐하면 getTax가 아직 정의 되지 않았는데 print를 하니까 nil 에러가 날겁니다. 먼저 변수나 함수를 정의하면 (call 되기 전에) 문제는 없을겁니다. 그런데 좀 예외적인 경우도 있습니다.

local getTax -- forward reference

local function printTax()

    print( getTax( 99.95 ) )
end

function getTax( num )

    return num * 0.0825
end

printTax()

이 경우에는 작동합니다. 우선 변수 getTx가 먼저 정의 됐구요. 그 다음에 getTax 함수가 정의 되기 전에 이 getTax 함수를 call 했습니다. 그리고 나서 getTax 함수를 만들었습니다. 이 경우는 getTax는 함수이기 때문에 printTax 함수 안에서 이 getTax를 call 하는 경우는 getTax 함수가 이미 정의되고 값이 할당 된 후이기 때문에 제대로 작동합니다.

자주 하는 실수는 아래와 같은 경우가 있습니다.

local getTax -- forward reference

local function printTax()

    print( getTax( 99.95 ) )
end

local function getTax( num )

    return num * 0.0825
end

printTax()

이렇게 하면 nil 에러가 발생합니다. 그 이유는 getTax 함수가 local 로 선언됐기 때문입니다. 이미 getTax 변수를 local로 선언했습니다. 그러고 나서 함수 앞에 또 한번 local 을 붙인다면 Lua 는 새로운 local 변수를 정의하게 됩니다. 그래서 원래의 getTax 변수는 nil이 되 버리는 거죠. 직접 이 코드에 local을 붙였다 뺐다 하고 함수 선언의 위치를 여기 저기 바꾸면서 한번 테스트 해 보시면 많은 도움이 될 겁니다.

모든 변수를 global로 선언하면 이런 문제는 발생하지 않겠죠. global로 선언하려면 그냥 local 글자를 빼면 됩니다. 이렇게 global로 몇개의 변수를 선언하는 건 괜찮을 겁니다. 하지만 변수가 무수히 많거나 퍼포먼스가 문제가 된다면 이 방법은 추천하고 싶지 않습니다. 그리고 많은 변수들과 함께 모듈을 로딩하는 경우에도 추천하지 않습니다.

변수와 관련되서는 더 많은 부분을 보실 수 있습니다. Lua 5.1 Reference Manual을 보시기 바랍니다.

Question 2

native.webPopup으로 웹사이트에 접근 했을 때 어떻게 HTTP status code를 얻을 수 있을까요?

Answer

HTTP Status Code 는 웹서버에서 return 되구요 이것은 HTTP request가 성공적으로 동작했는지 아닌지를 알 수 있도록 해 줍니다. 아래 흔히 받을 수 있는 status code들이 있습니다.

  • 200 OK
  • 301 Moved Permanenly
  • 404 Not Found
  • 500 Internal Server Error

이것과 관련된 좀 더 많은 정보는 여기로 가서 확인하세요.

코로나에서는 native.wevPopupnative.webView은 HTTP status code를 제공하지 않습니다. 다만 network.request에서는 제공합니다. (현재까지의 버전에서는요.). wepPopup이나 webView 의 event.isError는 서버에 연결되지 않았을 때 발생하는 겁니다. 서버에는 접속했는데 404에러 (page not found) 가 났다면 isError는 발생하지 않습니다. 이 HTTP Status Code를 받으시려면 웹페이지에 처음 접속할 때 network.request를 사용하셔야 합니다.

아래 그 예제가 있습니다.

local function loadWebPage()
    native.showWebPopup(10, 10, 300, 300, url )
end

local function networkListener( event )

    if( event.isError ) then
        print( "Network error: ", event.response )
    else
        print( "Status Code: " .. event.status )
        if event.status == 200 then
            print( "Loading web page ..." )
            loadWebPage()
        else
            print( "Web page not loaded!" )
        end
    end
end

network.request( url, "GET", networkListener )

이 코드는 웹 페이지에 접근할 때 먼저 network.request를 call 합니다. status가 200이라면 loadWebPage가 call 될 겁니다. 그리고 페이지는 native.webPopup을 이용해 로드 될 겁니다.

Note: native.webBiew는 iOS에서 native.webPopup 대신에 사용하려고 만든 겁니다. 이 메소드가 웹페이지를 표시할 때 사용하시기를 추천합니다. 이 API도 조만간에 안드로이드, 맥, 윈도우에서도 사용할 수 있도록 하겠습니다.

Question 3

내가 빌드 할 때 Ansca가 저의 소스를 보나요? 제 소스를 빌드하기 위해 정보가 당신의 서버에 전달할 때 어떻게 보안이 유지 되나요?

Answer

온라인 빌드가 일어날 때 우리의 서버는 절대 여러분의 raw source code를 보지 않습니다. 마찬가지로 여러분의 프로젝트 이미지, 사운드 또는 다른 asset들도 보지를 않습니다. Lua script는 우리 서버로 보내지기 전에 미리 bytecodes로 컴파일 됩니다. 서버에는 이 컴파일된 데이터를 처리할 코로나 엔진이 있습니다. 이 서버에서도 그 컴파일 된 파일을 절대 저장하거나 모아두지 않습니다.

Question 4

제가 API 페이지 (댓글란)에 버그 report를 했습니다. 그런데 왜 고쳐지지가 않죠?

Answer

API 페이지의 댓글란은 버그를 report 하거나 질문을 하는 곳이 아닙니다. 이 부분은 API documentation의 에러나 빠진 정보에 대해 report 하는 부분입니다.

만약에 API의 버그를 발견하셨다고 생각하시면 bug report를 해 주세요. 링크는 Forum과 Documentation 페이지의 윗쪽에 링크가 있습니다. 그리고 보내실 때는 되도록 자세히 적어서 보내 주세요. build number, 디바이스, OS 정보까지 포함해서요.

그리고 버그가 발생하는 경우의 전체 코드(config 파일등을 포함해서) 를 보내주시는 것이 중요합니다. 단지 코드 몇줄만 넣고 이 부분이 잘 안 된다고 설명만 하신다면 우리의 to do 리스트의 우선 순위에서 멀리 밀려날 겁니다. 저희는 아주 많은 버그 레포트를 받습니다. 이것을 가지고 샘플 테스트 케이스를 만들어서 문제점을 테스트 하는 것은 시간이 걸리는 일 입니다. 가끔 config.lua 파일이나 build.settings가 없어서 문제점을 찾지 못할 때도 있습니다. 버그가 여러분 문제를 해결하는데 중요한 부분이라면 그 전체 파일을 보내주시고 그 버그를 보려면 어떻게 해야 하는지에 대한 설명을 같이 보내 주세요.

저희는 지금 새로운 documentation system 을 만들고 있습니다. 그리고 곧 발표하게 될 겁니다. 이 새로운 시스템은 댓글란이 없습니다. 그 때는 API 관련 질문은 포럼이나 bug report를 이용하셔야 됩니다.

Question 5

제 코드를 디버그 하려고 print 구문을 넣었습니다. 그런데 nil 에러가 많이 나요. 이 에러를 피할 수 있는 방법이 있나요?

Answer

아마 아래 코드처럼 해서 그런 문제가 발생할 겁니다.

print( "lineNumber = " .. lineNumber )

scoping problem이나 이전에 set  때문에 lineNumber가 nil 이라면  print 구문은 이렇게 나올 겁니다. “attempt to concatenate ‘lineNumber’ (a nil value)”.

이걸 해결 하려면 두 변수를 분리하기 위해 , 를 사용하실 수 있습니다.

print( "lineNumber = " , lineNumber )

이 경우에 concatenation error를 피할 수 있습니다. 그런데 이렇게 하면 lineNumber 값을 print 하기 전에 원하지 않는 공간이 생길 겁니다.

“tostring”. 또 다른 방법으로는 tostring을 사용하는 방법이 있습니다.

print( "lineNumber = " .. tostring( lineNumber ) )

이렇게 하면 해당 값이 string으로 변환 됩니다. number, string , table, display object 등을 가리지 않고 심지어 그 값이 nil이라도 string으로 변환되죠.  이렇게 하면 print error 없이 print 구문을 사용할 수 있도록 해 줍니다.

여기까지가 오늘의 질문들 입니다. 여러분께 많은 도움이 됐기를 바랍니다.


반응형

Comment

  1. izowooi 2012.08.27 01:28

    감사합니다. 잘 읽었습니다.
    특히 2번에 함수 선언할 때 local 을 또 붙이는 문제는 생각지도 못했네요.