Mar 102016
 

윈도우에서 “bundler install”할 때 아래와 같은 에러가 발생했을 때 해결방법

C:\Ruby22\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:/Ruby22/bin/bundle install
Checksum of /versions does not match the checksum provided by server! Something
is wrong.

Process finished with exit code 17

의외로 간단하게 끝났다[1].

 

gem uninstall bundler
gem install bundler

번들러를 다시 깔아주면 해결되는 듯 하다.

 

참고문헌

[1] Rails initialization checksum error, Stackoverflow, http://stackoverflow.com/questions/35315712/rails-initialization-checksum-error

Jul 032014
 

윈도우에서 레일즈로 프로그래밍하면서 뭔가 한 번에 되는 것이 없다는 것을 자주 느끼곤 하는데, rmagick 이라는 gem을 설치할 때도 마찬가지 였다. rmagick은 오픈소스 이미지 프로세싱 라이브러리로 유명한 ImageMagick라는 라이브러리를 루비에서도 쓸 수 있게 wrapping한 gem이다. 전부가 그런 것은 아니고 C나 C++로 만들어진 대다수의 오픈소스 라이브러리는 크로스 컴파일을 지원하지만, 제일 컴파일하고 실행하기 좋은 환경은 리눅스 환경일 것이다. 어쨋든 rmagick을 윈도우에서 써야하는 이상 Gemfile에 rmagick을 넣고 bundle을 돌렸다. 역시나 에러 발생. 이런쪽 문제가 발생하면 구글에게 물어보라고 했던가, 검색하자마자 스택오버플로우 글 하나를 첫번째로 띄어주었다[1]. 글을 읽어보니 이전 포스팅에서 확인한 것과 같이 라이브러리를 설치해야한다는 것이였다. 별 생각없이 다운로드 받아서 실행해본 결과 역시나 실패. [1][2]의 글을 좀 열심히 읽어보니 라이브러리를 설치한 디렉토리에 빈칸이 있으면 안된다는 것이었다. “Program files”폴더에 설치 됬으니 당연히 빈칸이 들어갈 수 밖에… 지우고 다시 설치하였다. 그랬는데도 컴파일이 되지 않았다. 무엇 때문인지 하고 봤더니 ” c:\ImageMagick-6.8.0-3-Q16″에 “-“기호나 “.” 같은 특수문자 때문인듯 했다. 그래서 시키는 대로 “c:\ImageMagick” 폴더에 설치를 했다. 그랬더니 gem 설치가 성공하는 듯 했다. 하지만 이렇게 성공했다면 여기에 글을 남기지는 않았을 것이다. 역시나 안됬다. 에러를 뿌리면서 안됬는데 아래의 에러가 발생한다.

Building native extensions with: '--with-opt-lib=c:/ImageMagick/lib --with-opt-include=c:/ImageMagic
k/include'
This could take a while...
ERROR:  Error installing rmagick:
        ERROR: Failed to build gem native extension.

    C:/Ruby200/bin/ruby.exe extconf.rb --with-opt-lib=c:/ImageMagick/lib --with-opt-include=c:/Image
Magick/include
checking for Ruby version >= 1.8.5... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... yes
checking for snprintf() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wand
/MagickWand.h... yes
checking for AcquireImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,
wand/MagickWand.h... yes
checking for AffinityImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h
,wand/MagickWand.h... no
checking for AffinityImages() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... no
checking for AutoGammaImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys
/types.h,wand/MagickWand.h... yes
checking for AutoLevelImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys
/types.h,wand/MagickWand.h... yes
checking for BlueShiftImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... yes
checking for ConstituteComponentTerminus() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint
.h,sys/types.h,wand/MagickWand.h... no
checking for DeskewImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,w
and/MagickWand.h... yes
checking for EncipherImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h
,wand/MagickWand.h... yes
checking for EqualizeImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for FloodfillPaintImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/t
ypes.h,wand/MagickWand.h... yes
checking for FunctionImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for GetAuthenticIndexQueue() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sy
s/types.h,wand/MagickWand.h... yes
checking for GetAuthenticPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/ty
pes.h,wand/MagickWand.h... yes
checking for GetImageAlphaChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for GetVirtualPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... yes
checking for LevelImageColors() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... no
checking for LevelColorsImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,s
ys/types.h,wand/MagickWand.h... yes
checking for LevelizeImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for LiquidRescaleImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/ty
pes.h,wand/MagickWand.h... yes
checking for MagickLibAddendum() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/typ
es.h,wand/MagickWand.h... yes
checking for OpaquePaintImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,s
ys/types.h,wand/MagickWand.h... yes
checking for QueueAuthenticPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for RemapImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wa
nd/MagickWand.h... yes
checking for RemoveImageArtifact() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/t
ypes.h,wand/MagickWand.h... yes
checking for SelectiveBlurImageChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h
,sys/types.h,wand/MagickWand.h... yes
checking for SetImageAlphaChannel() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/
types.h,wand/MagickWand.h... yes
checking for SetImageArtifact() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... yes
checking for SetMagickMemoryMethods() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sy
s/types.h,wand/MagickWand.h... yes
checking for SparseColorImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/type
s.h,wand/MagickWand.h... yes
checking for SyncAuthenticPixels() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/t
ypes.h,wand/MagickWand.h... yes
checking for TransformImageColorspace() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,
sys/types.h,wand/MagickWand.h... yes
checking for TransparentPaintImage() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys
/types.h,wand/MagickWand.h... yes
checking for TransparentPaintImageChroma() in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint
.h,sys/types.h,wand/MagickWand.h... yes
checking for QueryMagickColorname() new signature... yes
checking for Image.type in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wand
/MagickWand.h... yes
checking for DrawInfo.kerning in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... yes
checking for DrawInfo.interline_spacing in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,
sys/types.h,wand/MagickWand.h... yes
checking for DrawInfo.interword_spacing in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,
sys/types.h,wand/MagickWand.h... yes
checking for DitherMethod in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wa
nd/MagickWand.h... yes
checking for MagickFunction in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,
wand/MagickWand.h... yes
checking for ImageLayerMethod in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.
h,wand/MagickWand.h... yes
checking for long double in assert.h,ctype.h,stdio.h,stdlib.h,math.h,time.h,stdint.h,sys/types.h,wan
d/MagickWand.h... yes
checking for AlphaChannelType.CopyAlphaChannel... yes
checking for AlphaChannelType.BackgroundAlphaChannel... yes
checking for CompositeOperator.BlurCompositeOp... yes
checking for CompositeOperator.DistortCompositeOp... yes
checking for CompositeOperator.LinearBurnCompositeOp... yes
checking for CompositeOperator.LinearDodgeCompositeOp... yes
checking for CompositeOperator.MathematicsCompositeOp... yes
checking for CompositeOperator.PegtopLightCompositeOp... yes
checking for CompositeOperator.PinLightCompositeOp... yes
checking for CompositeOperator.VividLightCompositeOp... yes
checking for CompressionType.DXT1Compression... yes
checking for CompressionType.DXT3Compression... yes
checking for CompressionType.DXT5Compression... yes
checking for CompressionType.ZipSCompression... yes
checking for CompressionType.PizCompression... yes
checking for CompressionType.Pxr24Compression... yes
checking for CompressionType.B44Compression... yes
checking for CompressionType.B44ACompression... yes
checking for DistortImageMethod.BarrelDistortion... yes
checking for DistortImageMethod.BarrelInverseDistortion... yes
checking for DistortImageMethod.BilinearForwardDistortion... yes
checking for DistortImageMethod.BilinearReverseDistortion... yes
checking for DistortImageMethod.DePolarDistortion... yes
checking for DistortImageMethod.PolarDistortion... yes
checking for DistortImageMethod.PolynomialDistortion... yes
checking for DistortImageMethod.ShepardsDistortion... yes
checking for DitherMethod.NoDitherMethod... yes
checking for FilterTypes.KaiserFilter... yes
checking for FilterTypes.WelshFilter... yes
checking for FilterTypes.ParzenFilter... yes
checking for FilterTypes.LagrangeFilter... yes
checking for FilterTypes.BohmanFilter... yes
checking for FilterTypes.BartlettFilter... yes
checking for FilterTypes.SentinelFilter... yes
checking for MagickEvaluateOperator.PowEvaluateOperator... yes
checking for MagickEvaluateOperator.LogEvaluateOperator... yes
checking for MagickEvaluateOperator.ThresholdEvaluateOperator... yes
checking for MagickEvaluateOperator.ThresholdBlackEvaluateOperator... yes
checking for MagickEvaluateOperator.ThresholdWhiteEvaluateOperator... yes
checking for MagickEvaluateOperator.GaussianNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.ImpulseNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.LaplacianNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.MultiplicativeNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.PoissonNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.UniformNoiseEvaluateOperator... yes
checking for MagickEvaluateOperator.CosineEvaluateOperator... yes
checking for MagickEvaluateOperator.SineEvaluateOperator... yes
checking for MagickEvaluateOperator.AddModulusEvaluateOperator... yes
checking for MagickFunction.ArcsinFunction... yes
checking for MagickFunction.ArctanFunction... yes
checking for MagickFunction.PolynomialFunction... yes
checking for MagickFunction.SinusoidFunction... yes
checking for ImageLayerMethod.FlattenLayer... yes
checking for ImageLayerMethod.MergeLayer... yes
checking for ImageLayerMethod.MosaicLayer... yes
checking for ImageLayerMethod.TrimBoundsLayer... yes
checking for VirtualPixelMethod.HorizontalTileVirtualPixelMethod... yes
checking for VirtualPixelMethod.VerticalTileVirtualPixelMethod... yes
checking for VirtualPixelMethod.HorizontalTileEdgeVirtualPixelMethod... yes
checking for VirtualPixelMethod.VerticalTileEdgeVirtualPixelMethod... yes
checking for VirtualPixelMethod.CheckerTileVirtualPixelMethod... yes
checking for ruby/io.h... yes
checking for rb_frame_this_func() in ruby.h,ruby/io.h... yes
creating extconf.h
creating Makefile


======================================================================
Thu 03Jul14 22:29:32
This installation of RMagick 2.13.2 is configured for
Ruby 2.0.0 (i386-mingw32) and ImageMagick 6.8.9
======================================================================



make "DESTDIR="
generating RMagick2-i386-mingw32.def
compiling rmagick.c
In file included from rmagick.c:13:0:
rmagick.h:81:2: error: #error Specified QuantumDepth is not supported.
rmagick.c: In function 'Magick_colors':
rmagick.c:40:5: warning: implicit declaration of function 'GetExceptionInfo' [-Wimplicit-function-de
claration]
rmagick.c:42:5: warning: passing argument 2 of 'GetColorInfoList' from incompatible pointer type [en
abled by default]
In file included from c:/ImageMagick/include/magick/image.h:21:0,
                 from c:/ImageMagick/include/magick/draw.h:22,
                 from c:/ImageMagick/include/magick/fx.h:21,
                 from c:/ImageMagick/include/magick/accelerate.h:21,
                 from c:/ImageMagick/include/magick/MagickCore.h:73,
                 from rmagick.h:47,
                 from rmagick.c:13:
c:/ImageMagick/include/magick/color.h:75:5: note: expected 'size_t *' but argument is of type 'long
unsigned int *'
rmagick.c: In function 'Magick_fonts':
rmagick.c:90:5: warning: passing argument 2 of 'GetTypeInfoList' from incompatible pointer type [ena
bled by default]
In file included from c:/ImageMagick/include/magick/draw.h:24:0,
                 from c:/ImageMagick/include/magick/fx.h:21,
                 from c:/ImageMagick/include/magick/accelerate.h:21,
                 from c:/ImageMagick/include/magick/MagickCore.h:73,
                 from rmagick.h:47,
                 from rmagick.c:13:
c:/ImageMagick/include/magick/type.h:98:5: note: expected 'size_t *' but argument is of type 'long u
nsigned int *'
rmagick.c: In function 'Magick_init_formats':
rmagick.c:178:5: warning: passing argument 2 of 'GetMagickInfoList' from incompatible pointer type [
enabled by default]
In file included from c:/ImageMagick/include/magick/MagickCore.h:118:0,
                 from rmagick.h:47,
                 from rmagick.c:13:
c:/ImageMagick/include/magick/magick.h:135:5: note: expected 'size_t *' but argument is of type 'lon
g unsigned int *'
make: *** [rmagick.o] Error 1


Gem files will remain installed in C:/Ruby200/lib/ruby/gems/2.0.0/gems/rmagick-2.13.2 for inspection
.
Results logged to C:/Ruby200/lib/ruby/gems/2.0.0/gems/rmagick-2.13.2/ext/RMagick/gem_make.out

또 열심히 구글링을 했더니 [3]의 문서를 발견하였다. 문서를 간단히 살펴보니 imagemagick 라이브러리의 버젼에 따라서 컴파일이 안된다는 말로 간단히 요약할 수 있었다. 직접 컴파일해서 연동하는 방법도 써있으니 필요하신분은 참고하시면 될 듯. 어쨋든 되는 버젼을 확인해보니 ‘ImageMagick-6.8.7-8-Q16-x86-dll’에서는 컴파일이 가능하다고 하여 다운로드 받아서 위와 같은 방법으로 실행해 보니 문제 없이 설치할 수 있었다. 이상으로 문제 해결!

– 필자는 Ruby 2.0 x86에서 테스트 했으며, ImageMagick라이브러리도 x86으로 준비하였음. 전에 64bit로 무리하게 진행하다가 고생한 선례가 있어 그나마 편하게 가고 싶으시면 x86을 추천함.

 

요 약


1. http://ftp.sunet.se/pub/multimedia/graphics/ImageMagick/binaries/ 에서 ImageMagick-6.8.7.8-Q16-x86-dll.exe 을 다운로드.

2. ImageMagick 설치시 경로를 “c:\ImageMagick” 으로 할 것. 그리고 설치시 체크하는 곳에서 “Add application directory to your path system”, “Install development headers and libraries for C and C++” 항목을 체크표시 할 것

3. rails 폴더에서 “gem install rmagick –platform=ruby — –with-opt-lib=c:/ImageMagick/lib –with-opt-include=c:/ImageMagick/include” 라고 명령 실행!

 

참고자료


[1] StackOverflow(I cant install gem on windows), http://stackoverflow.com/questions/4873276/i-cant-install-rmagick-gem-on-windows
[2] shubham’s blog(installing rmagick gem on windows 7), http://shoobm.wordpress.com/2013/01/03/installing-rmagick-gem-on-windows-7/
[3] 君の瞳はまるでルビー – Ruby 関連まとめサイト(RMagick を Windows 7 にインストールする方法), http://www.ownway.info/Ruby/index.php?rmagick%2Fhowtoinstall%2Fwindows

May 172014
 

여러 삽질을 하면서 알아낸 정보! 시작은 아래의 에러 메시지로부터 시작되었다. mysql2 gem을 성공적으로 설치하고 기쁨에 잠겨있던 필자는 즐겁게 rails 서버를 켰다. 문제없이 서버가 켜졌다. 하지만 scss파일을 가져오는데 실패한 것이였다. 윈도우에는 한 번에 가는 일이 없는 것 같다. 에러메시지는 아래와 같다.

ArgumentError at / different prefix: "C:/" and "G:/*****/******/app/assets/stylesheets" (in G:/*****/******/app/assets/stylesheets/home.css.scss)

보아하니 디렉토리 앞의 prefix(여기서는 드라이브)가 다르다는 에러였다. 왜 그렇게 만들었는지는 모르겠지만(아마도 보안 문제일까??) 구글링을 해본 결과 크게 세가지의 해결방법이 있었다. 물론 아래 방법 이외에도 있을 수 있다.

1. gem과 같은 드라이브로 프로젝트를 옮긴다.

용량이 없다거나 관리 문제가 없다면 이 방법이 제일 간단한 방법인 것 같다. 보통 루비가 설치된 드라이브로 옮기면 되겠다. 같은 드라이브라면 어디에 놓던 문제 없다.

2. symbolic link를 이용하는 방법

윈도우에는 심볼릭 링크 개념이 없었지만 ntfs로 넘어오면서 비슷한 역할을 하는 명령어가 생겼다. 아래의 명령을 실행한다. (만약 실행이 안된다면 윈도우 버젼이 낮아서 그런 것이니 [1]에 들어가서 확인해보자)

mklink /j c:\application g:\*****\application

3. gem을 프로젝트 폴더에 설치하는 방법

아래와 같이 bundle install을 실행할 때 옵션을 붙여서 실행한다. 그러면 문제 없이 사용할 수 있다.

bundle install --path .bundle

참고 자료

[1] Stackoverflow(Error “different prefix:” with Active_Admin gem), http://stackoverflow.com/questions/7740002/error-different-prefix-with-active-admin-gem

May 112014
 

윈도우에서 아래와 같은 에러가 발생하는 경우 루비 실행파일이 mysql connector 라이브러리인 “libmysql.dll”을 찾지 못해서 발생할 가능성이 높다.

126: The specified module could not be found.   - C:/Ruby193/lib/ruby/gems/1.9.1/gems/mysql2-0.3.15/lib/mysql2/mysql2.so

mysql가 설치된 폴더의 lib폴더에서 “libmysql.dll”을 windows의 system 폴더(플랫폼x86/x64 주의)에 복사하거나 루비가 설치된 폴더의 bin 폴더(예: c:\ruby193\bin)에 복사를 하도록 하자. 그러면 문제가 해결된다. 자세한 내용은 [1]을 참조하자.

 

참고 자료

[1] http://stackoverflow.com/questions/4241068/rubymine-3-0-setup-on-windows-7

May 102014
 

모든 것은 mysql서버를 설치하지 않고 rails를 하려고 한 것에서 시작되었다. 아래와 같은 문제의 경우, 사용하는 ruby의 플렛폼(x86/x64 여부)와 관련된 문제다. 에러 내용이 link 에러여서 좀 더 유심히 보았다. 그랬더니 얻은 결론! mysql connector는 x64 버젼이고 루비는 x86이였던 것이다. 작동 플렛폼이 다르니 당연히 발생하는 문제였다. 아이구… 어쨋든, 여기에서 x86버젼 커넥터를 받아서 설치하여서 경로를 약간 수정해 다시 실행하였더니 성공적으로 설치되었다.

 

1. 해결 방법

1) mysql connect (x86)버젼을 다운로드 받는다.

2) 아래 명령을 실행한다.

C:\Ruby193\bin>gem install mysql2 --platform=ruby -- '--with-mysql-lib="C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\lib" --with-mysql-include="C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\include"'

 

2. 에러 메시지

C:/Ruby193/bin/ruby.exe extconf.rb --width-mysql-lib="C:\Program Files\M
ySQL\MySQL Connector C 6.1\lib" --width-mysql-include="C:\Program Files\MySQL\My
SQL Connector C 6.1\include" --with-mysql-dir="C:\Program Files\MySQL\MySQL Conn
ector C 6.1"
checking for ruby/thread.h... no
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for rb_hash_dup()... yes
checking for rb_intern3()... yes
-----
Using --with-mysql-dir=C:\Program Files\MySQL\MySQL Connector C 6.1
-----
checking for main() in -llibmysql... yes
checking for mysql.h... yes
checking for errmsg.h... yes
checking for mysqld_error.h... yes
-----
Setting rpath to /lib
-----
creating Makefile

make
generating mysql2-i386-mingw32.def
compiling client.c
client.c: In function 'finish_and_mark_inactive':
client.c:513:3: warning: ISO C90 forbids mixed declarations and code
compiling infile.c
compiling mysql2_ext.c
compiling result.c
result.c: In function 'rb_mysql_result_fetch_fields':
result.c:415:35: warning: comparison between signed and unsigned integer express
ions
linking shared-object mysql2/mysql2.so
client.o: In function `nogvl_connect':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:157: undef
ined reference to `mysql_real_connect@32'
client.o: In function `nogvl_init':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:146: undef
ined reference to `mysql_init@4'
client.o: In function `set_ssl_options':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:1102: unde
fined reference to `mysql_ssl_set@24'
client.o: In function `mysql_client_options':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:744: undef
ined reference to `mysql_options@12'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:748: undef
ined reference to `mysql_error@4'
client.o: In function `rb_mysql_info':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:271: undef
ined reference to `mysql_info@4'
client.o: In function `rb_mysql_client_warning_count':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:261: undef
ined reference to `mysql_warning_count@4'
client.o: In function `nogvl_do_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:375: undef
ined reference to `mysql_store_result@4'
client.o: In function `rb_mysql_client_more_results':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:947: undef
ined reference to `mysql_more_results@4'
client.o: In function `nogvl_select_db':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:887: undef
ined reference to `mysql_select_db@8'
client.o: In function `nogvl_ping':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:918: undef
ined reference to `mysql_ping@4'
client.o: In function `rb_mysql_client_thread_id':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:880: undef
ined reference to `mysql_thread_id@4'
client.o: In function `rb_mysql_client_last_id':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:849: undef
ined reference to `mysql_insert_id@4'
client.o: In function `nogvl_read_query_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:362: undef
ined reference to `mysql_read_query_result@4'
client.o: In function `rb_mysql_client_server_info':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:809: undef
ined reference to `mysql_get_server_version@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:810: undef
ined reference to `mysql_get_server_info@4'
client.o: In function `rb_mysql_client_info':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:777: undef
ined reference to `mysql_get_client_version@0'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:778: undef
ined reference to `mysql_get_client_info@0'
client.o: In function `rb_mysql_client_real_escape':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:667: undef
ined reference to `mysql_real_escape_string@16'
client.o: In function `finish_and_mark_inactive':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:520: undef
ined reference to `mysql_free_result@4'
client.o: In function `nogvl_send_query':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:339: undef
ined reference to `mysql_send_query@12'
client.o: In function `nogvl_close':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:189: undef
ined reference to `mysql_close@4'
client.o: In function `rb_mysql_client_escape':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:242: undef
ined reference to `mysql_escape_string@12'
client.o: In function `rb_raise_mysql2_error':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:125: undef
ined reference to `mysql_error@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:126: undef
ined reference to `mysql_sqlstate@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:135: undef
ined reference to `mysql_errno@4'
client.o: In function `rb_connect':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:301: undef
ined reference to `mysql_errno@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:309: undef
ined reference to `mysql_get_server_version@4'
client.o: In function `rb_mysql_client_store_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:990: undef
ined reference to `mysql_errno@4'
client.o: In function `rb_mysql_client_next_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:963: undef
ined reference to `mysql_next_result@4'
client.o: In function `rb_mysql_client_affected_rows':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:863: undef
ined reference to `mysql_affected_rows@4'
client.o: In function `rb_mysql_client_async_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:424: undef
ined reference to `mysql_errno@4'
client.o: In function `rb_mysql_client_abandon_results':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:544: undef
ined reference to `mysql_next_result@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:543: undef
ined reference to `mysql_more_results@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:552: undef
ined reference to `mysql_free_result@4'
client.o: In function `nogvl_do_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:373: undef
ined reference to `mysql_use_result@4'
client.o: In function `nogvl_close':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:189: undef
ined reference to `mysql_close@4'
client.o: In function `set_charset_name':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:1091: unde
fined reference to `mysql_options@12'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:1093: unde
fined reference to `mysql_error@4'
client.o: In function `nogvl_close':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:189: undef
ined reference to `mysql_close@4'
client.o: In function `init_mysql2_client':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/client.c:1141: unde
fined reference to `mysql_get_client_info@0'
infile.o: In function `mysql2_set_local_infile':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/infile.c:114: undef
ined reference to `mysql_set_local_infile_handler'
result.o: In function `rb_mysql_result_count':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:592: undef
ined reference to `mysql_num_rows@4'
result.o: In function `rb_mysql_result_fetch_field':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:123: undef
ined reference to `mysql_fetch_field_direct@8'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:111: undef
ined reference to `mysql_num_fields@4'
result.o: In function `rb_mysql_result_fetch_fields':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:411: undef
ined reference to `mysql_num_fields@4'
result.o: In function `nogvl_fetch_row':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:102: undef
ined reference to `mysql_fetch_row@4'
result.o: In function `rb_mysql_result_free_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:76: undefi
ned reference to `mysql_free_result@4'
result.o: In function `rb_mysql_result_fetch_row':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:209: undef
ined reference to `mysql_fetch_lengths@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:211: undef
ined reference to `mysql_num_fields@4'
result.o: In function `rb_mysql_result_each':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:512: undef
ined reference to `mysql_fetch_fields@4'
result.o: In function `rb_mysql_result_free_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:76: undefi
ned reference to `mysql_free_result@4'
result.o: In function `rb_mysql_result_each':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:530: undef
ined reference to `mysql_error@4'
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:547: undef
ined reference to `mysql_fetch_fields@4'
result.o: In function `rb_mysql_result_free_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:76: undefi
ned reference to `mysql_free_result@4'
result.o: In function `rb_mysql_result_each':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:499: undef
ined reference to `mysql_num_rows@4'
result.o: In function `rb_mysql_result_free_result':
C:\Ruby193\lib\ruby\gems\1.9.1\gems\mysql2-0.3.15\ext\mysql2/result.c:76: undefi
ned reference to `mysql_free_result@4'
collect2: ld returned 1 exit status
make: *** [mysql2.so] Error 1


Gem files will remain installed in C:/Ruby193/lib/ruby/gems/1.9.1/gems/mysql2-0.
3.15 for inspection.
Results logged to C:/Ruby193/lib/ruby/gems/1.9.1/gems/mysql2-0.3.15/ext/mysql2/g
em_make.out

 

May 102014
 

필자의 경우에 회사에서는 MacBook을 이용하고 집에서는 Windows기반의 데스크톱을 이용하고 있다. 회사에는 듀얼모니터가 있기 때문에 작업하는데 딱히 불편함을 느끼지 못 하였다. 하지만 집에는 여분의 모니터가 없고, 이미 데스크톱에 20인치의 듀얼모니터를 이용하고 있기 때문에 데스크톱쪽이 더 효율이 잘 나온다. 물론 집에까지 회사일을 들고와서 하는 것에 대해서는 크게 신경쓰지 말도록 하자. 어쨋든 어차피 회사에서 주로 하는 ruby는 스크립트 언어이고 멀티 플렛폼을 지원하니 집의 윈도우 데스크톱에 ruby를 직접 설치해 보기로 하였다. 필자는 단순히 ruby설치해서 실행시키면 될 것으로 기대했지만, 안타깝게도 설치/설정해야 할 것이 좀 있었다. 아래를 참고해 보도록 하자.

 

1. Ruby 설치

http://rubyinstaller.org/downloads/ 에서 기존 프로젝트에서 사용하던 버젼의 ruby 인스톨 패키지를 설치한다.

 

2. Development Kit(이하 devkit)  설치

몇몇 루비 gem은 네이티브 컴파일을 하기도 하는데 이 경우에 development kit이 필요하다. 해당하는 루비버젼과, 사용자 시스템에 맞는 것을 찾아서 설치 한다.

* 예를들어 json gem의 경우 아래와 같은 에러가 발생하면 devkit를 설치하고 환경변수까지 잡아주어야 한다[1].

ERROR:Error installing json:The'json' native gem requires installed build tools.

* devkit 설치 방법

1) devkit 설치경로: c:\ruby193\devkit

2) ruby 1.9.3 설치경로: c:\ruby193

3) 아래 3개의 명령 실행

c:\ruby193\devkit> ..\bin\ruby dk.rb init

c:\ruby193\devkit> ..\bin\ruby dk.rb review

c:\ruby193\devkit> ..\bin\ruby dk.rb install

* gem 설치시 아래와 같은 에러가 난다면..[2] [3]  (이러한 에러의 발생 이유에 대한 자세한 설명은 [3]를 참조)

1) 여기에서 rebase.exe를 다운로드 받음

2) devkit밑의 bin폴더에 복사 (예:  c:\ruby193\devkit\bin)

3) 아래의 명령을 실행

c:\> cd ruby183\devkit\bin

c:\ruby193\devkit\bin> rebase -b 0x30000000 msys-1.0.dll

 3. Let’s programming!

‘bundle install’ 하고 작업 시작하자! 혹시 mysql에서 또 에러메시지를 본다면 여기, 여기2를 참조하자!!

 

4. 참고 자료


[1] stackoverflow(The ‘json’ native gem requires installed build tools),  http://stackoverflow.com/questions/8100891/the-json-native-gem-requires-installed-build-tools

[2] stackoverflow(Error installing gem: Couldn’t reserve space for cygwin’s heap, Win32 error 487), http://stackoverflow.com/questions/19259272/error-installing-gem-couldnt-reserve-space-for-cygwins-heap-win32-error-487

[3] 아자님의 블로그([MSYS] *** Couldn’t reserve space for cygwin’s heap (0xXXXXXXXX <0xXXXXXXX>) in child, Win32 error 0),  http://azza.tistory.com/152

Jan 022014
 

현재 운영중인 jinukbaek.com 홈페이지는 블로그 페이지에 들어오기 위해 "jinukbaek.com/blog"까지 입력을 해야한다. 하지만 jinukbaek.com 도메인으로는 현재 블로그 밖에 운영하고 있지 않기 때문에 자동으로 이동(리다이렉션, Redirection)되게 해두었다. 하지만 문제는 Javascript로 이동하게 해두었다는 점에 있었다.

Redirection

Javascript와 301리다이렉션과 차이는 빨간색부분이지만 웹브라우져는 200의 경우 html코드를 실행을 해야하기 때문에 반응 속도는 좀 더 늦다.

웹 브라우져는 "http://jinukbaek.com"으로 접속을 먼저 하게 되면 서버는 특별한 설정을 하지 않았다는 전제하에 index.html을 찾아서 그림과 같이 "200 OK"라는 메시지와 index.html의 내용을 같이 보내게 된다. 이 파일을 웹 브라우져는 읽어 들여서 실행을 하게 된다. 요는 불러와서 자바스크립트를 따로 실행해야한다는 점에 있다. 비록 필자가 "jinukbaek.com/blog"로 이동하라는 코드를 넣어놨다 하더라도 웹 브라우져 입장에서는 html파일의 내용이 무엇일지 예측할 수 없기 때문에 일단 실행을 해야한다. 하지만 301과 같이 상태코드(300대의 상태 코드는 페이지 이동을 나타냄)를 이용해서 리다이렉션을 하기 때문에 딱히 내용을 확인하지 않아도 바로 이동하도록 하게 할 수 있다. 그래서 속도 향상과 검색봇이 크롤링1을 제대로 하게 된다. 제일 좋은 것은 "jinukbaek.com/blog" 주소를 블로그로 쓰지 않고 "jinukbaek.com"에 바로 블로그가 연결되도록 하는 것이 좋지만, 추후에 다른 서비스 확장도 고려하고 있는 필자의 입장에서는 어쩔 수 없는 선택이였다.

구글의 경우에는 자바스크립트까지 분석해서 크롤링하는지 모르겠지만 내용도 문제없이 검색이 되었었는데 네이버는 상황이 다른 듯 했다. 네이버 검색 신청을 하고 키워드로 검색해도 결과가 안나와서 "블로그 RSS 등록2" 을 찾아서 신청해야 했다. 다음의 경우에도 "블로그 RSS 등록3"을 통해서 검색이 되도록 하였다. 그렇게 검색이 안되는 문제를 해결하였다. 필자가 블로그 사이트를 만든지 시간이 꽤 지났기 때문에 Javascript를 통해서 리다이렉션을 했었는지 완전 잊고 있었다. 그런데 그렇게 했는지 다시 확인하게 된 것은 한 신문기사 때문이였다.

(9) JavaScript나 flash로 redirect 하지 말 것4

필자가 설마하고 확인을 해 보았더니 정말로 자바스크립트로 블로그페이지로 이동되게 되어 있었다. 봇이 자바스크립트까지 해석하지는 않을태니 당연히 크롤링이 안됬고 따라서 검색이 안되는 것이었다. 아마 "index.html" 파일 만들고 코드 몇 줄 입력하면 되기 때문에 그렇게 했을 것이다. 자바스크립트 리다이렉션은 서버 재시작이나 설정을 바꾼다거나 하는 작업 없이 아래 코드를 입력하면 된다.

<script>
	window.location = "/blog";
</script>

이참에 문제있는 부분도 수정할겸 아파치 서버 설정을 바꾸어 "http://jinukbaek.com"으로 접속하면 301 코드를 리턴하여 이동하도록 수정하였다. 수정한 환경설정 파일 경로는 "/etc/apache2/sites-enable/000-default.conf"이며 사용자 환경에 따라서 경로는 달라질 수도 있다. 수정은 환경설정 파일의 상황에 따라서 달라지는데 보통 VirtualHost 태그 사이에 넣으면 된다. 수정하고 나서 아파치 서버를 제시작(sudo service apache2 restart) 하는 것을 잊지 말자.

RedirectMatch 301 ^/$ /blog 
# RedirectMatch : 요청 주소가 해당하는 정규표현식을 만족할 경우 리다이렉션
# 301 : 리다이렉션시 http응답 코드
# ^/$ : 시작시 "/"로 시작하고 끝나는 문자열에 대해서. (즉 "/"로 요청이 왔을 때만)
# /blog : "/blog" 경로로 리다이렉션

리다이렉션시 웹브라우져가 자바스크립트 파싱하고 실행하는 상황이 생략되었기 때문에 초기 접속 속도가 약간 향상 되었으며 네이버에서 RSS내용 이외의 것도 검색이 되기 시작하였다. 이것으로써 서버운영하면서 있었던 문제 하나를 해결하였다.

참고자료

  1. 웹 크롤러, http://ko.wikipedia.org/wiki/%EC%9B%B9_%ED%81%AC%EB%A1%A4%EB%9F%AC
  2. 네이버 도움말, https://help.naver.com/ops/step2/mail.nhn?catg=547&upCatg=264
  3. 다음 검색 등록, https://register.search.daum.net/index.daum
  4. 한세희, "네이버 검색에 잘 걸리는 웹페이지 만들기 비법은?", 전자신문, 2013년 12월 20일
Dec 312013
 

아래와 같은 에러를 내면서 “gem install rmagick”이 실패할 경우, 아래의 “checking for wand/MagickWand.h”를 주의깊게 보자. magickwand 라이브러리가 설치되어 있지 않기 때문에 발생하는 것이다.

root@wminserver:/home/redmine/redmine/redmine-2.4# gem install rmagick
Building native extensions.  This could take a while...
ERROR:  Error installing rmagick:
	ERROR: Failed to build gem native extension.

    /usr/local/rvm/rubies/ruby-2.1.0/bin/ruby extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... yes
checking for ImageMagick version >= 6.4.9... yes
checking for HDRI disabled version of ImageMagick... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... no

Can't install RMagick 2.13.2. Can't find MagickWand.h.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/usr/local/rvm/rubies/ruby-2.1.0/bin/ruby

extconf failed, exit code 1

Gem files will remain installed in /usr/local/rvm/gems/ruby-2.1.0/gems/rmagick-2.13.2 for inspection.
Results logged to /usr/local/rvm/gems/ruby-2.1.0/extensions/x86_64-linux/2.1.0/rmagick-2.13.2/gem_make.out

 

해결방법

libmagickwand-dev를 설치해 줌으로써 해결이 된다. 아래의 명령을 실행시켜보도록 하자.

$ sudo apt-get install libmagickwand-dev
$ gem install rmagick

문제없이 잘 설치 될 것이다.

Reference

[1] Stack Overflow(Can’t install RMagick 2.13.1. Can’t find MagickWand.h), http://stackoverflow.com/questions/9050419/cant-install-rmagick-2-13-1-cant-find-magickwand-h

Dec 162013
 

루비(Ruby)언어 정리

소스코드를 통하여 주요한 기능만 확인해보고 넘어간다.

클래스와 객체

class Car
    @@run_car = 0  # 클래스 변수 / static 변수

    attr_reader :pos    # 읽기 전용 속성(attribute)
    attr_writer :pos    # 쓰기 전용 속성
    attr_accessor :light # 읽기/쓰기 가능 속성

    def initialize(color) # 생성자
        @color = color  # @는 멤버변수 없는 것은 지역변수
    end

    def get_color
        return @color
    end

    def get_run_car
        return @@run_car
    end

    def Car.run(num)  # 클래스 메소드 | static 함수
        @@run_car += num
    end

    def id_car()  # id_car값 반환 접근자 메소드
        @id_car
    end

    def id_car=(id_car)  # pos값 쓰기 접근자 메소드
        @id_car = id_car
    end

protected # 메소드 공개 범위 (JAVA와 같음)
    def alaram
    end

private # 메소드 공개 범위 (JAVA와 같음)
    def check 
    end
end

class SuperCar < Car   # 상속
   def initialize(color)
       super(color)  # 부모 생성자 호출
   end

   def get_color
       return "red"
   end
end

supercar = SuperCar.new("blue") # 인스턴스 생성
Car.run(100) # 클래스 메소드 호출 

모듈

module Computer
    def Computer.buy(com)
        puts com + " buy"
    end

    class CPU
        def CPU.run
            puts cpu + " run"
        end
    end
end

include "computer.pb" # 외부 루비 파일 입포트
Computer.buy "Alpha"
Computer::CPU.run   # module의 class는 ::을 이용하여 접근한다.

모듈 혼합

module LeftClick
    def lclick
        puts "Left Clicked"
    end
end

module RightClick
    def rclick
        puts "Right Clicked"
    end
end 

class Mouse
    include LeftClick
    include RightClick
end

mouse = Mouse.new() # Mouse는 LeftClick, RightClick 2가지 기능이 혼합된다. (다중상속), Module은 인스턴스 생성이 불가하나 Mouse는 class이므로 가능
Dec 162013
 

루비(Ruby)언어 정리

조건문

if

if Boolean [then | :]
   code1
[elsif Boolean [then | :]
   code
]...
[else
   code ]
end
  • Boolean : 식의 Return 값이 Boolean형인 결과 값
  • code1 : 조건(Boolean)이 참일 경우 실행
  • elsif : elseif 가 아니고 elsif인 것에 주의할 것

unless

if문과 반대로 작동함

unless Boolean [then | :]
   code1
[else
   code ]
end
  • Boolean : 식의 Return 값이 Boolean형인 결과 값
  • code1 : 조건(Boolean)이 거짓일 경우 실행

if/unless를 수식어 형태로 사용

puts "true" if res > 100 : 100보다 클 경우 true를 출력

puts "false" if new <= 100 : 100 이하일 경우 false를 출력

case 문

case value
when expression [, comparision]... [then | :]
   code
when expression [, comparision]... [then | :]
   code
.
.
.
[else
    code]
end

조건에 알맞는 value값에 대해 when의 조건에 맞는 것을 실행함

goal = 100
case goal
when 95..100
    puts "A+"
when 90...95
    puts "A"
when 85...90
    puts "B+"
when 80...85
    puts "B"
when 75...80
    puts "C+"
when 70...75
    puts "C"
else
    puts "F"
end

위와 같은 형식으로 Range와 함께 사용 가능

? 연산자

condition ? true : false 형식으로 이용.

예제: res = r >= 70 ? "pass" : "fail"

순환문

while

while condition [ do | : ]
   code
end 

condition의 조건이 참일 경우에만 실행

until

until condition [ do | : ]
    code
end

condition의 조건을 만족할 때 까지 실행

while/until의 수식어 형태 사용

value += 10 until value == 100

value += 1 while value < 100

for

for variable [, variable]... in collection [do | :]
    code
end

collection을 차례대로 variable에 넣으면서 code를 실행한다.

  • 예제 1
for value in 1..10
   data += value
end
  • 예제 2
for data in ["I", "love", "you"]
   puts data
end

Ruby Iterator

collection do |variable|
   code
end

collection의 내용을 variable에 하나씩 넣으면서 code를 실행. 아래는 이를 사용한 예제.

data = ["Hello", "World", "!!"]
res = ""

0.upto(grades.length - 1) do |loop_index|
    res = data[loop_index] + " "
end

puts res
  • 0.upto(n) : 0부터 n까지 순환문을 만듬
  • 10.downto(0) : 10부터 0까지 값을 감소시키며 순환
  • 2.step(11, 3) : 11까지 2부터 3씩 증가시키는 순환문 작성(예 : 2, 5, 8, 11)
  • 5.times : 5회 반복
  • data.each : data가 컬렉션이면 모든 항목들을 순서대로 가져옴
  • loop : 무한 루프 (break문을 통해서 반복문 탈출)

반복문에서 사용할 수 있는 구문

  • break : 반복문을 탈출
  • redo : 반복문의 현재 단계를 한 번 더 실행
  • next : 다음 단계를 실행함 (C++/JAVA++의 continue와 같음)
  • retry : 반복문을 처음부터 다시 시작

메소드 정의

hello란 이름의 메소드 정의

def hello
   puts "Hello World!!"
end

사용 방법은 hello라고 하는 것 만으로 가능

  • 메개변수 전달방법
def hello(name)
   puts "Hello World!!, " + name
end

hello "Gildong"
  • 가변 개수
def hello(data, *others)
    puts data + "!! Hello World!! " + others.join(", ")
end

hello "Ruby", "Gildong", "Gilsoon", "Cheolsoo"

Ruby에서 *는 배열이라는 뜻임. 파라미터를 넘길 경우에도 사용 가능

  • 메소드 값을 리턴
def sum(a, b)
    return a + b
end
  • 2개 이상의 값 리턴
def sum_minus(a, b)
    return a+b, a-b
end
arr = sum_minus(30, 20)   # 배열 형태
s, m = sum_minus(30, 20)  # 각각 리턴값이 s, m으로 리턴
  • 변수의 유효 범위

동일 이름일 경우에 매소드 내부가 최우선

  • 블록 (block)

메소드에 파라미터(Parameter)처럼 전달될 수 있는 코드를 말함, {}를 이용하여 작성

{ puts "Hello World!!" }

또는

do
   puts "Hello World!!" 
end

형태로 작성 가능함

yield문을 이용하여 블록을 실행할 수 있다.

def hello
    yield
end

hello { puts "Hello World!!" }
  • 블록에 데이터 전달
def hello
   yield "Ruby", "Gildong"
end

hello { |word1, word2| puts word1 + " Hello World!! " + word2 }

||안에 있는 변수에 차례대로 데이터가 전달된다.

  • 반복자와 함께 블록 사용
["Hello", "World", "!!"].each {|word| puts word}
4.times {puts "!"}
  • BEGIN/END 블록
BEGIN {puts "Hi "}

puts "Hello World!"

END { puts "Bye!" }

Ruby 프로그램이 메모리에 올라갈 때 BEGIN 블록이 실행 되며 종료 될 때 END 블록이 실행된다.